From 3503b62ff290f7897ca1f0cf304dbc6b630152c0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 3 Oct 2015 15:33:55 +0800 Subject: [PATCH 01/56] Disable logging unless --enable-logging is specified --- atom/app/atom_main_delegate.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/atom/app/atom_main_delegate.cc b/atom/app/atom_main_delegate.cc index 3c7d6b2e70..fe3c0e09ae 100644 --- a/atom/app/atom_main_delegate.cc +++ b/atom/app/atom_main_delegate.cc @@ -27,10 +27,10 @@ AtomMainDelegate::~AtomMainDelegate() { } bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { - // Disable logging out to debug.log on Windows logging::LoggingSettings settings; #if defined(OS_WIN) #if defined(DEBUG) + // Print logging to debug.log on Windows settings.logging_dest = logging::LOG_TO_ALL; settings.log_file = L"debug.log"; settings.lock_log = logging::LOCK_LOG_FILE; @@ -41,6 +41,12 @@ bool AtomMainDelegate::BasicStartupComplete(int* exit_code) { #else // defined(OS_WIN) settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; #endif // !defined(OS_WIN) + + // Only enable logging when --enable-logging is specified. + auto command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(switches::kEnableLogging)) + settings.logging_dest = logging::LOG_NONE; + logging::InitLogging(settings); // Logging with pid and timestamp. From 55acdcb1ad3e999f9f0ac5cd115203216ed25989 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 3 Oct 2015 15:43:26 +0800 Subject: [PATCH 02/56] docs: --enable-logging --- docs/api/chrome-command-line-switches.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/api/chrome-command-line-switches.md b/docs/api/chrome-command-line-switches.md index cd633fc046..c2a39126f6 100644 --- a/docs/api/chrome-command-line-switches.md +++ b/docs/api/chrome-command-line-switches.md @@ -89,15 +89,21 @@ Enables net log events to be saved and writes them to `path`. ## --ssl-version-fallback-min=`version` -Set the minimum SSL/TLS version ("tls1", "tls1.1" or "tls1.2") that TLS +Sets the minimum SSL/TLS version ("tls1", "tls1.1" or "tls1.2") that TLS fallback will accept. +## --enable-logging + +Prints Chromium's logging into console. + +This switch can not be used in `app.commandLine.appendSwitch` since it is parsed earlier than user's app is loaded. + ## --v=`log_level` Gives the default maximal active V-logging level; 0 is the default. Normally positive values are used for V-logging levels. -Passing `--v=-1` will disable logging. +This switch only works when `--enable-logging` is also passed. ## --vmodule=`pattern` @@ -109,10 +115,4 @@ Any pattern containing a forward or backward slash will be tested against the whole pathname and not just the module. E.g. `*/foo/bar/*=2` would change the logging level for all code in the source files under a `foo/bar` directory. -To disable all chromium related logs and only enable your application logs you -can do: - -```javascript -app.commandLine.appendSwitch('v', -1); -app.commandLine.appendSwitch('vmodule', 'console=0'); -``` +This switch only works when `--enable-logging` is also passed. From b78bb8442406cd6df63966b851ab59928dd92b3a Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Sat, 3 Oct 2015 17:54:05 +0900 Subject: [PATCH 03/56] Update as upstream --- docs-translations/ko-KR/README.md | 1 + .../ko-KR/api/chrome-command-line-switches.md | 18 ++++++------- docs-translations/ko-KR/api/menu-item.md | 2 +- .../ko-KR/tutorial/supported-platforms.md | 26 +++++++++++++++++++ .../tutorial/using-selenium-and-webdriver.md | 2 +- 5 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 docs-translations/ko-KR/tutorial/supported-platforms.md diff --git a/docs-translations/ko-KR/README.md b/docs-translations/ko-KR/README.md index 1e0ba63e7b..9b88aa6e17 100644 --- a/docs-translations/ko-KR/README.md +++ b/docs-translations/ko-KR/README.md @@ -1,5 +1,6 @@ ## 개발 가이드 +* [지원하는 플랫폼](tutorial/supported-platforms.md) * [어플리케이션 배포](tutorial/application-distribution.md) * [어플리케이션 패키징](tutorial/application-packaging.md) * [네이티브 Node 모듈 사용하기](tutorial/using-native-node-modules.md) diff --git a/docs-translations/ko-KR/api/chrome-command-line-switches.md b/docs-translations/ko-KR/api/chrome-command-line-switches.md index 2d9158fcc2..777ce4612d 100644 --- a/docs-translations/ko-KR/api/chrome-command-line-switches.md +++ b/docs-translations/ko-KR/api/chrome-command-line-switches.md @@ -84,13 +84,19 @@ Net log 이벤트를 활성화하고 `path`에 로그를 기록합니다. ## --ssl-version-fallback-min=`version` -Fallback SSL/TLS 최소 버전을 지정합니다. ("tls1", "tls1.1", "tls1.2") +TLS fallback에서 사용할 SSL/TLS 최소 버전을 지정합니다. ("tls1", "tls1.1", "tls1.2") + +## --enable-logging + +Chromium의 로그를 콘솔에 출력합니다. + +이 스위치는 어플리케이션이 로드되기 전에 파싱 되므로 `app.commandLine.appendSwitch`에서 사용할 수 없습니다. ## --v=`log_level` 기본 V-logging 최대 활성화 레벨을 지정합니다. 기본값은 0입니다. 기본적으로 양수를 레벨로 사용합니다. -`--v=-1`를 사용하면 로깅이 비활성화 됩니다. +이 스위치는 `--enable-logging` 스위치를 같이 지정해야 작동합니다. ## --vmodule=`pattern` @@ -100,10 +106,4 @@ Fallback SSL/TLS 최소 버전을 지정합니다. ("tls1", "tls1.1", "tls1.2") 또한 슬래시(`/`) 또는 백슬래시(`\`)를 포함하는 패턴은 지정한 경로에 대해 패턴을 테스트 합니다. 예를 들어 `*/foo/bar/*=2` 표현식은 `foo/bar` 디렉터리 안의 모든 소스 코드의 로깅 레벨을 2로 지정합니다. -모든 크로미움과 관련된 로그를 비활성화하고 어플리케이션의 로그만 활성화 하려면 다음과 같이 코드를 작성하면 됩니다: - - -```javascript -app.commandLine.appendSwitch('v', -1); -app.commandLine.appendSwitch('vmodule', 'console=0'); -``` +이 스위치는 `--enable-logging` 스위치를 같이 지정해야 작동합니다. diff --git a/docs-translations/ko-KR/api/menu-item.md b/docs-translations/ko-KR/api/menu-item.md index 8f10210099..e4c5c67767 100644 --- a/docs-translations/ko-KR/api/menu-item.md +++ b/docs-translations/ko-KR/api/menu-item.md @@ -1,6 +1,6 @@ # MenuItem -`menu-item` 모듈은 어플리케이션 또는 컨텐츠 [`menu`](menu.md)에 아이템을 추가할 수 있도록 관련 클래스를 제공합니다. +`menu-item` 모듈은 어플리케이션 또는 컨텍스트 [`menu`](menu.md)에 아이템을 추가할 수 있도록 관련 클래스를 제공합니다. [`menu`](menu.md)에서 예제를 확인할 수 있습니다. diff --git a/docs-translations/ko-KR/tutorial/supported-platforms.md b/docs-translations/ko-KR/tutorial/supported-platforms.md new file mode 100644 index 0000000000..7a35da0c12 --- /dev/null +++ b/docs-translations/ko-KR/tutorial/supported-platforms.md @@ -0,0 +1,26 @@ +# 지원하는 플랫폼 + +Electron에선 다음과 같은 플랫폼을 지원합니다: + +### OS X + +OS X는 64비트 바이너리만 제공됩니다. 그리고 최소 OS X 지원 버전은 10.8입니다. + +### Windows + +Windows 7 이후 버전만 지원됩니다. Windows Vista에서도 작동할 수 있지만 아직 모든 작동 테스트가 완료되지 않았습니다. + +윈도우용 바이너리는 `x86`과 `x64` 모두 제공됩니다. 그리고 `ARM` 버전 윈도우는 아직 지원하지 않습니다. (역주: 추후 지원할 가능성이 있습니다) + +### Linux + +Ubuntu 12.04 버전에서 빌드된 `ia32`(`i686`), `x64`(`amd64`) 바이너리가 제공됩니다. +그리고 `arm` 버전 바이너리는 ARM v7 hard-float ABI와 Debian Wheezy용 NEON에 맞춰 제공됩니다. + +미리 빌드된 바이너리가 배포판에서 작동할 수 있는지 여부는 Electron이 빌드된 플랫폼에서 링크된 라이브러리에 따라 달라집니다. +그래서 현재 Linux 바이너리는 Ubuntu 12.04 버전만 정상적인 작동이 보장됩니다. +하지만 다음 플랫폼들은 미리 빌드된 Electron 바이너리가 정상적으로 작동하는 것을 확인했습니다: + +* Ubuntu 12.04 이후 버전 +* Fedora 21 +* Debian 8 diff --git a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md index 33dc6311ce..a9fd84a68b 100644 --- a/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md +++ b/docs-translations/ko-KR/tutorial/using-selenium-and-webdriver.md @@ -71,7 +71,7 @@ driver.quit(); 먼저, `chromedriver` 바이너리를 다운로드 받고 실행합니다: ```bash -$ chromedriver --url-base=/wd/hub --port=9515 +$ chromedriver --url-base=wd/hub --port=9515 Starting ChromeDriver (v2.10.291558) on port 9515 Only local connections are allowed. ``` From 021ee20400ea4636090fb41213f3dcfd1770edf6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 3 Oct 2015 17:52:46 +0800 Subject: [PATCH 04/56] No need to add "app" to search paths --- atom/renderer/lib/init.coffee | 3 --- 1 file changed, 3 deletions(-) diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index 274c50ec5f..ff9b12ecbf 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -11,9 +11,6 @@ process.argv.splice 1, 1 # of Atom's built-in libraries. globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') -# And also app. -globalPaths.push path.join(process.resourcesPath, 'app') -globalPaths.push path.join(process.resourcesPath, 'app.asar') # Import common settings. require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') From 9fe326ebeb43ffb2c955945ca8b4a2135efb08c2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 3 Oct 2015 19:55:59 +0800 Subject: [PATCH 05/56] Clear node's global search paths --- atom/browser/lib/init.coffee | 6 +++--- atom/common/lib/init.coffee | 13 ++----------- atom/renderer/lib/init.coffee | 6 +++--- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 454baf0b8a..44ae29522e 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -7,14 +7,14 @@ Module = require 'module' # we need to restore it here. process.argv.splice 1, 1 +# Import common settings. +require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') + # Add browser/api/lib to module search paths, which contains javascript part of # Electron's built-in libraries. globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') -# Import common settings. -require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') - if process.platform is 'win32' # Redirect node's console to use our own implementations, since node can not # handle console output when running as GUI program. diff --git a/atom/common/lib/init.coffee b/atom/common/lib/init.coffee index acb635edea..2bfea3d72a 100644 --- a/atom/common/lib/init.coffee +++ b/atom/common/lib/init.coffee @@ -9,18 +9,9 @@ process.atomBinding = (name) -> catch e process.binding "atom_common_#{name}" if /No such module/.test e.message -# Global module search paths. +# Clear node's global search paths. globalPaths = Module.globalPaths - -# Don't lookup modules in user-defined search paths, see http://git.io/vf8sF. -homeDir = - if process.platform is 'win32' - process.env.USERPROFILE - else - process.env.HOME -if homeDir # Node only add user-defined search paths when $HOME is defined. - userModulePath = path.resolve homeDir, '.node_modules' - globalPaths.splice globalPaths.indexOf(userModulePath), 2 +globalPaths.length = 0 # Add common/api/lib to module search paths. globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index ff9b12ecbf..e5173fcd1e 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -7,14 +7,14 @@ Module = require 'module' # atom-renderer.js, we need to restore it here. process.argv.splice 1, 1 +# Import common settings. +require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') + # Add renderer/api/lib to require's search paths, which contains javascript part # of Atom's built-in libraries. globalPaths = Module.globalPaths globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') -# Import common settings. -require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') - # The global variable will be used by ipc for event dispatching v8Util = process.atomBinding 'v8_util' v8Util.setHiddenValue global, 'ipc', new events.EventEmitter From 01d2765e4b566df853cd583006ebc7993d48cd38 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sat, 3 Oct 2015 20:38:39 +0800 Subject: [PATCH 06/56] Prevent Node from adding paths outside this app to search paths --- atom/browser/lib/init.coffee | 3 +++ atom/common/lib/init.coffee | 6 +---- atom/common/lib/reset-search-paths.coffee | 29 +++++++++++++++++++++++ atom/renderer/lib/init.coffee | 3 +++ filenames.gypi | 1 + 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 atom/common/lib/reset-search-paths.coffee diff --git a/atom/browser/lib/init.coffee b/atom/browser/lib/init.coffee index 44ae29522e..b394c0fecc 100644 --- a/atom/browser/lib/init.coffee +++ b/atom/browser/lib/init.coffee @@ -7,6 +7,9 @@ Module = require 'module' # we need to restore it here. process.argv.splice 1, 1 +# Clear search paths. +require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths') + # Import common settings. require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') diff --git a/atom/common/lib/init.coffee b/atom/common/lib/init.coffee index 2bfea3d72a..1c80e6171a 100644 --- a/atom/common/lib/init.coffee +++ b/atom/common/lib/init.coffee @@ -9,12 +9,8 @@ process.atomBinding = (name) -> catch e process.binding "atom_common_#{name}" if /No such module/.test e.message -# Clear node's global search paths. -globalPaths = Module.globalPaths -globalPaths.length = 0 - # Add common/api/lib to module search paths. -globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') +Module.globalPaths.push path.resolve(__dirname, '..', 'api', 'lib') # setImmediate and process.nextTick makes use of uv_check and uv_prepare to # run the callbacks, however since we only run uv loop on requests, the diff --git a/atom/common/lib/reset-search-paths.coffee b/atom/common/lib/reset-search-paths.coffee new file mode 100644 index 0000000000..7061103306 --- /dev/null +++ b/atom/common/lib/reset-search-paths.coffee @@ -0,0 +1,29 @@ +path = require 'path' +Module = require 'module' + +# Clear Node's global search paths. +Module.globalPaths.length = 0 + +# Clear current and parent(init.coffee)'s search paths. +module.paths = [] +module.parent.paths = [] + +# Prevent Node from adding paths outside this app to search paths. +Module._nodeModulePaths = (from) -> + from = path.resolve from + + # If "from" is outside the app then we do nothing. + skipOutsidePaths = from.startsWith process.resourcesPath + + # Following logoic is copied from module.js. + splitRe = if process.platform is 'win32' then /[\/\\]/ else /\// + paths = [] + + parts = from.split splitRe + for part, tip in parts by -1 + continue if part is 'node_modules' + dir = parts.slice(0, tip + 1).join path.sep + break if skipOutsidePaths and not dir.startsWith process.resourcesPath + paths.push path.join(dir, 'node_modules') + + paths diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index e5173fcd1e..b7224b39ae 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -7,6 +7,9 @@ Module = require 'module' # atom-renderer.js, we need to restore it here. process.argv.splice 1, 1 +# Clear search paths. +require path.resolve(__dirname, '..', '..', 'common', 'lib', 'reset-search-paths') + # Import common settings. require path.resolve(__dirname, '..', '..', 'common', 'lib', 'init') diff --git a/filenames.gypi b/filenames.gypi index 0e7010d7a4..000633fb96 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -37,6 +37,7 @@ 'atom/common/api/lib/native-image.coffee', 'atom/common/api/lib/shell.coffee', 'atom/common/lib/init.coffee', + 'atom/common/lib/reset-search-paths.coffee', 'atom/renderer/lib/chrome-api.coffee', 'atom/renderer/lib/init.coffee', 'atom/renderer/lib/inspector.coffee', From bb938b02d8f3b32079c4d555e50df6b9647df43b Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Sat, 3 Oct 2015 09:02:50 -0700 Subject: [PATCH 07/56] Remove Vista as possibly working Vista crashes on startup because Win7 touch APIs aren't present - this is fine, but we want to tell people out of the gate that it won't work --- docs/tutorial/supported-platforms.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/supported-platforms.md b/docs/tutorial/supported-platforms.md index 8b795769a8..f74ccf2ec2 100644 --- a/docs/tutorial/supported-platforms.md +++ b/docs/tutorial/supported-platforms.md @@ -8,9 +8,9 @@ Only 64bit binaries are provided for OS X, and the minimum OS X version supporte ### Windows -Windows 7 and later are supported, Electron should be able to run on Windows Vista, but there is no testing done on it. +Windows 7 and later are supported, older operating systems are not supported (and do not work). -Both `x86` and `x64` binaries are provided for Windows, and `ARM` version of Windows is not supported for now. +Both `x86` and `amd64` (x64) binaries are provided for Windows, and `ARM` version of Windows is not supported for now. ### Linux From b4ec7c5aaf09d7125124658f269954cacc1765c0 Mon Sep 17 00:00:00 2001 From: chriswmercer Date: Sat, 3 Oct 2015 18:03:49 +0100 Subject: [PATCH 08/56] Minor grammar correction --- docs/tutorial/supported-platforms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial/supported-platforms.md b/docs/tutorial/supported-platforms.md index 8b795769a8..ec0f3ef6a1 100644 --- a/docs/tutorial/supported-platforms.md +++ b/docs/tutorial/supported-platforms.md @@ -10,7 +10,7 @@ Only 64bit binaries are provided for OS X, and the minimum OS X version supporte Windows 7 and later are supported, Electron should be able to run on Windows Vista, but there is no testing done on it. -Both `x86` and `x64` binaries are provided for Windows, and `ARM` version of Windows is not supported for now. +Both `x86` and `x64` binaries are provided for Windows. Please note, the `ARM` version of Windows is not supported for now. ### Linux From aea1f8aebb8faf71c2c54c815b72ad9a8c21a88e Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Sat, 3 Oct 2015 22:09:57 +0300 Subject: [PATCH 09/56] Fix calculating min/max size in frameless views The minimum and maximum size that frameless windows had used, was incorrect. It included the border, so when it was called it actually added that to the size, so window increased in size. The fix makes sure that the view will use the frameless size. This fixes #2945 and partially fixes #1806 (it also refers to some other issues with hidpi which might still exist). --- atom/browser/native_window_views.cc | 29 +++++++++++++++++++++++-- atom/browser/native_window_views.h | 2 ++ atom/browser/ui/views/frameless_view.cc | 8 +++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e9db97e195..40d702e35a 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -818,9 +818,7 @@ bool NativeWindowViews::ExecuteWindowsCommand(int command_id) { NotifyWindowExecuteWindowsCommand(command); return false; } -#endif -#if defined(OS_WIN) bool NativeWindowViews::PreHandleMSG( UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) { switch (message) { @@ -874,6 +872,33 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { } #endif +gfx::Size NativeWindowViews::WindowSizeToFramelessSize( + const gfx::Size& size) { + if (size.width() == 0 && size.height() == 0) + return size; + + gfx::Rect window_bounds = gfx::Rect(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) + gfx::Size frame_size = gfx::win::ScreenToDIPRect( + window_->non_client_view()->GetWindowBoundsForClientBounds( + gfx::Rect())).size(); +#else + gfx::Size frame_size = + window_->non_client_view()->GetWindowBoundsForClientBounds( + gfx::Rect()).size(); +#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(); +} + void NativeWindowViews::HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 71e122d381..790e532f84 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -94,6 +94,8 @@ class NativeWindowViews : public NativeWindow, gfx::AcceleratedWidget GetAcceleratedWidget(); + gfx::Size WindowSizeToFramelessSize(const gfx::Size& size); + views::Widget* widget() const { return window_.get(); } #if defined(OS_WIN) diff --git a/atom/browser/ui/views/frameless_view.cc b/atom/browser/ui/views/frameless_view.cc index 03a31e0828..e8d351ec82 100644 --- a/atom/browser/ui/views/frameless_view.cc +++ b/atom/browser/ui/views/frameless_view.cc @@ -104,11 +104,15 @@ gfx::Size FramelessView::GetPreferredSize() const { } gfx::Size FramelessView::GetMinimumSize() const { - return window_->GetMinimumSize(); + gfx::Size size = window_->WindowSizeToFramelessSize( + window_->GetMinimumSize()); + return size; } gfx::Size FramelessView::GetMaximumSize() const { - return window_->GetMaximumSize(); + gfx::Size size = window_->WindowSizeToFramelessSize( + window_->GetMaximumSize()); + return size; } const char* FramelessView::GetClassName() const { From 5d7cfa1b3ac5b3f578ceca6ceb94dcbddedd4dcf Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 15:53:09 +0800 Subject: [PATCH 10/56] Update brightray for atom/brightray#149 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 6cbb4ad4d1..361d99dd05 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 6cbb4ad4d173d25b66eecf675c2b25ee64196429 +Subproject commit 361d99dd05a8368faee20bc39a6ffaedbc67c383 From 791f988aba568921c940713231da1811b6a1cdd3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 16:32:08 +0800 Subject: [PATCH 11/56] linux: Fix pressing Alt not showing menubar --- atom/browser/native_window_views.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e9db97e195..4282b0eda9 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -905,9 +905,6 @@ void NativeWindowViews::HandleKeyboardEvent( // When a single Alt is pressed: menu_bar_alt_pressed_ = true; } else if (event.type == blink::WebInputEvent::KeyUp && IsAltKey(event) && -#if defined(USE_X11) - event.modifiers == 0 && -#endif menu_bar_alt_pressed_) { // When a single Alt is released right after a Alt is pressed: menu_bar_alt_pressed_ = false; From add9c380230ae61316156025ef8c9fec85d23f84 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 16:33:03 +0800 Subject: [PATCH 12/56] linux: Enable force showing menubar This is for debugging purpose. --- atom/browser/ui/x/x_window_utils.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/atom/browser/ui/x/x_window_utils.cc b/atom/browser/ui/x/x_window_utils.cc index e57122839c..f5c3f54ec1 100644 --- a/atom/browser/ui/x/x_window_utils.cc +++ b/atom/browser/ui/x/x_window_utils.cc @@ -6,6 +6,7 @@ #include +#include "base/environment.h" #include "base/strings/string_util.h" #include "dbus/bus.h" #include "dbus/object_proxy.h" @@ -50,6 +51,10 @@ void SetWindowType(::Window xwindow, const std::string& type) { } bool ShouldUseGlobalMenuBar() { + scoped_ptr env(base::Environment::Create()); + if (env->HasVar("ELECTRON_FORCE_WINDOW_MENU_BAR")) + return false; + dbus::Bus::Options options; scoped_refptr bus(new dbus::Bus(options)); From 74b76102a84740a618ff3288f27dfad1197d32a2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 16:53:20 +0800 Subject: [PATCH 13/56] linux: No longer needs to manually read DPI settings It is now done in brightray by reading the value from GTK+. --- atom/browser/atom_browser_main_parts.cc | 4 - atom/browser/atom_browser_main_parts.h | 4 - atom/browser/atom_browser_main_parts_linux.cc | 73 ------------------- filenames.gypi | 1 - vendor/brightray | 2 +- 5 files changed, 1 insertion(+), 83 deletions(-) delete mode 100644 atom/browser/atom_browser_main_parts_linux.cc diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index a1a1192b27..1b46247c49 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -55,10 +55,6 @@ void AtomBrowserMainParts::RegisterDestructionCallback( void AtomBrowserMainParts::PostEarlyInitialization() { brightray::BrowserMainParts::PostEarlyInitialization(); -#if defined(USE_X11) - SetDPIFromGSettings(); -#endif - { // 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 diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index bcebc86f16..9fefa486a1 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -48,10 +48,6 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { #endif private: -#if defined(USE_X11) - void SetDPIFromGSettings(); -#endif - // A fake BrowserProcess object that used to feed the source code from chrome. scoped_ptr fake_browser_process_; diff --git a/atom/browser/atom_browser_main_parts_linux.cc b/atom/browser/atom_browser_main_parts_linux.cc deleted file mode 100644 index 278e49ac1f..0000000000 --- a/atom/browser/atom_browser_main_parts_linux.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) 2014 GitHub, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#include "atom/browser/atom_browser_main_parts.h" - -#include - -#include "base/command_line.h" -#include "base/strings/string_number_conversions.h" -#include "ui/gfx/switches.h" - -namespace atom { - -namespace { - -const char* kInterfaceSchema = "org.gnome.desktop.interface"; -const char* kScaleFactor = "scaling-factor"; - -bool SchemaExists(const char* schema_name) { - const gchar* const* schemas = g_settings_list_schemas(); - while (*schemas) { - if (strcmp(schema_name, static_cast(*schemas)) == 0) - return true; - schemas++; - } - return false; -} - -bool KeyExists(GSettings* client, const char* key) { - gchar** keys = g_settings_list_keys(client); - if (!keys) - return false; - - gchar** iter = keys; - while (*iter) { - if (strcmp(*iter, key) == 0) - break; - iter++; - } - - bool exists = *iter != NULL; - g_strfreev(keys); - return exists; -} - -void GetDPIFromGSettings(guint* scale_factor) { - GSettings* client = nullptr; - if (!SchemaExists(kInterfaceSchema) || - !(client = g_settings_new(kInterfaceSchema))) { - VLOG(1) << "Cannot create gsettings client."; - return; - } - - if (KeyExists(client, kScaleFactor)) - *scale_factor = g_settings_get_uint(client, kScaleFactor); - - g_object_unref(client); -} - -} // namespace - -void AtomBrowserMainParts::SetDPIFromGSettings() { - guint scale_factor = 1; - GetDPIFromGSettings(&scale_factor); - if (scale_factor == 0) - scale_factor = 1; - - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kForceDeviceScaleFactor, base::UintToString(scale_factor)); -} - -} // namespace atom diff --git a/filenames.gypi b/filenames.gypi index 000633fb96..eb94973e01 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -124,7 +124,6 @@ 'atom/browser/atom_download_manager_delegate.h', 'atom/browser/atom_browser_main_parts.cc', 'atom/browser/atom_browser_main_parts.h', - 'atom/browser/atom_browser_main_parts_linux.cc', 'atom/browser/atom_browser_main_parts_mac.mm', 'atom/browser/atom_javascript_dialog_manager.cc', 'atom/browser/atom_javascript_dialog_manager.h', diff --git a/vendor/brightray b/vendor/brightray index 361d99dd05..bbb9287337 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 361d99dd05a8368faee20bc39a6ffaedbc67c383 +Subproject commit bbb9287337f8b7958b001be35b993c21cd573109 From bdd2f919137546a560ce808fd386994823628c57 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 19:20:52 +0800 Subject: [PATCH 14/56] Make Browser::Quit more robust --- atom/browser/browser.cc | 15 +++++++++++++-- atom/browser/browser.h | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index 9d2a9fc1ef..d8bb94103c 100644 --- a/atom/browser/browser.cc +++ b/atom/browser/browser.cc @@ -16,7 +16,8 @@ namespace atom { Browser::Browser() : is_quiting_(false), - is_ready_(false) { + is_ready_(false), + is_shutdown_(false) { WindowList::AddObserver(this); } @@ -30,6 +31,9 @@ Browser* Browser::Get() { } void Browser::Quit() { + if (is_quiting_) + return; + is_quiting_ = HandleBeforeQuit(); if (!is_quiting_) return; @@ -42,9 +46,13 @@ void Browser::Quit() { } void Browser::Shutdown() { - FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit()); + if (is_shutdown_) + return; + is_shutdown_ = true; is_quiting_ = true; + + FOR_EACH_OBSERVER(BrowserObserver, observers_, OnQuit()); base::MessageLoop::current()->PostTask( FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); } @@ -121,6 +129,9 @@ void Browser::ClientCertificateSelector( } void Browser::NotifyAndShutdown() { + if (is_shutdown_) + return; + bool prevent_default = false; FOR_EACH_OBSERVER(BrowserObserver, observers_, OnWillQuit(&prevent_default)); diff --git a/atom/browser/browser.h b/atom/browser/browser.h index d135556b87..3c5abd2f04 100644 --- a/atom/browser/browser.h +++ b/atom/browser/browser.h @@ -159,6 +159,9 @@ class Browser : public WindowListObserver { // Whether "ready" event has been emitted. bool is_ready_; + // The browse is being shutdown. + bool is_shutdown_; + std::string version_override_; std::string name_override_; From 0e131f760b63ad199c5fffa13b2d422cf3bb5e26 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 19:21:36 +0800 Subject: [PATCH 15/56] Quit gracefully when Ctrl-C is pressed --- atom/browser/atom_browser_main_parts.cc | 12 + atom/browser/atom_browser_main_parts.h | 8 + atom/browser/atom_browser_main_parts_posix.cc | 225 ++++++++++++++++++ filenames.gypi | 1 + 4 files changed, 246 insertions(+) create mode 100644 atom/browser/atom_browser_main_parts_posix.cc diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index 1b46247c49..e70d42fc76 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -52,6 +52,12 @@ void AtomBrowserMainParts::RegisterDestructionCallback( destruction_callbacks_.push_back(callback); } +void AtomBrowserMainParts::PreEarlyInitialization() { +#if defined(OS_POSIX) + HandleSIGCHLD(); +#endif +} + void AtomBrowserMainParts::PostEarlyInitialization() { brightray::BrowserMainParts::PostEarlyInitialization(); @@ -112,6 +118,12 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { #endif } +void AtomBrowserMainParts::PostMainMessageLoopStart() { +#if defined(OS_POSIX) + HandleShutdownSignals(); +#endif +} + void AtomBrowserMainParts::PostMainMessageLoopRun() { brightray::BrowserMainParts::PostMainMessageLoopRun(); diff --git a/atom/browser/atom_browser_main_parts.h b/atom/browser/atom_browser_main_parts.h index 9fefa486a1..65b142157d 100644 --- a/atom/browser/atom_browser_main_parts.h +++ b/atom/browser/atom_browser_main_parts.h @@ -39,8 +39,10 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { protected: // content::BrowserMainParts: + void PreEarlyInitialization() override; void PostEarlyInitialization() override; void PreMainMessageLoopRun() override; + void PostMainMessageLoopStart() override; void PostMainMessageLoopRun() override; #if defined(OS_MACOSX) void PreMainMessageLoopStart() override; @@ -48,6 +50,12 @@ class AtomBrowserMainParts : public brightray::BrowserMainParts { #endif private: +#if defined(OS_POSIX) + // Set signal handlers. + void HandleSIGCHLD(); + void HandleShutdownSignals(); +#endif + // A fake BrowserProcess object that used to feed the source code from chrome. scoped_ptr fake_browser_process_; diff --git a/atom/browser/atom_browser_main_parts_posix.cc b/atom/browser/atom_browser_main_parts_posix.cc new file mode 100644 index 0000000000..ea0f87b171 --- /dev/null +++ b/atom/browser/atom_browser_main_parts_posix.cc @@ -0,0 +1,225 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +// Most code came from: chrome/browser/chrome_browser_main_posix.cc. + +#include "atom/browser/atom_browser_main_parts.h" + +#include +#include +#include +#include +#include +#include + +#include "atom/browser/browser.h" +#include "base/posix/eintr_wrapper.h" +#include "content/public/browser/browser_thread.h" + +using content::BrowserThread; + +namespace atom { + +namespace { + +// See comment in |PreEarlyInitialization()|, where sigaction is called. +void SIGCHLDHandler(int signal) { +} + +// The OSX fork() implementation can crash in the child process before +// fork() returns. In that case, the shutdown pipe will still be +// shared with the parent process. To prevent child crashes from +// causing parent shutdowns, |g_pipe_pid| is the pid for the process +// which registered |g_shutdown_pipe_write_fd|. +// See . +pid_t g_pipe_pid = -1; +int g_shutdown_pipe_write_fd = -1; +int g_shutdown_pipe_read_fd = -1; + +// Common code between SIG{HUP, INT, TERM}Handler. +void GracefulShutdownHandler(int signal) { + // Reinstall the default handler. We had one shot at graceful shutdown. + struct sigaction action; + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_DFL; + RAW_CHECK(sigaction(signal, &action, NULL) == 0); + + RAW_CHECK(g_pipe_pid == getpid()); + RAW_CHECK(g_shutdown_pipe_write_fd != -1); + RAW_CHECK(g_shutdown_pipe_read_fd != -1); + size_t bytes_written = 0; + do { + int rv = HANDLE_EINTR( + write(g_shutdown_pipe_write_fd, + reinterpret_cast(&signal) + bytes_written, + sizeof(signal) - bytes_written)); + RAW_CHECK(rv >= 0); + bytes_written += rv; + } while (bytes_written < sizeof(signal)); +} + +// See comment in |PostMainMessageLoopStart()|, where sigaction is called. +void SIGHUPHandler(int signal) { + RAW_CHECK(signal == SIGHUP); + GracefulShutdownHandler(signal); +} + +// See comment in |PostMainMessageLoopStart()|, where sigaction is called. +void SIGINTHandler(int signal) { + RAW_CHECK(signal == SIGINT); + GracefulShutdownHandler(signal); +} + +// See comment in |PostMainMessageLoopStart()|, where sigaction is called. +void SIGTERMHandler(int signal) { + RAW_CHECK(signal == SIGTERM); + GracefulShutdownHandler(signal); +} + +class ShutdownDetector : public base::PlatformThread::Delegate { + public: + explicit ShutdownDetector(int shutdown_fd); + + void ThreadMain() override; + + private: + const int shutdown_fd_; + + DISALLOW_COPY_AND_ASSIGN(ShutdownDetector); +}; + +ShutdownDetector::ShutdownDetector(int shutdown_fd) + : shutdown_fd_(shutdown_fd) { + CHECK_NE(shutdown_fd_, -1); +} + +// These functions are used to help us diagnose crash dumps that happen +// during the shutdown process. +NOINLINE void ShutdownFDReadError() { + // Ensure function isn't optimized away. + asm(""); + sleep(UINT_MAX); +} + +NOINLINE void ShutdownFDClosedError() { + // Ensure function isn't optimized away. + asm(""); + sleep(UINT_MAX); +} + +NOINLINE void ExitPosted() { + // Ensure function isn't optimized away. + asm(""); + sleep(UINT_MAX); +} + +void ShutdownDetector::ThreadMain() { + base::PlatformThread::SetName("CrShutdownDetector"); + + int signal; + size_t bytes_read = 0; + ssize_t ret; + do { + ret = HANDLE_EINTR( + read(shutdown_fd_, + reinterpret_cast(&signal) + bytes_read, + sizeof(signal) - bytes_read)); + if (ret < 0) { + NOTREACHED() << "Unexpected error: " << strerror(errno); + ShutdownFDReadError(); + break; + } else if (ret == 0) { + NOTREACHED() << "Unexpected closure of shutdown pipe."; + ShutdownFDClosedError(); + break; + } + bytes_read += ret; + } while (bytes_read < sizeof(signal)); + VLOG(1) << "Handling shutdown for signal " << signal << "."; + base::Closure task = + base::Bind(&Browser::Quit, base::Unretained(Browser::Get())); + + if (!BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, task)) { + // Without a UI thread to post the exit task to, there aren't many + // options. Raise the signal again. The default handler will pick it up + // and cause an ungraceful exit. + RAW_LOG(WARNING, "No UI thread, exiting ungracefully."); + kill(getpid(), signal); + + // The signal may be handled on another thread. Give that a chance to + // happen. + sleep(3); + + // We really should be dead by now. For whatever reason, we're not. Exit + // immediately, with the exit status set to the signal number with bit 8 + // set. On the systems that we care about, this exit status is what is + // normally used to indicate an exit by this signal's default handler. + // This mechanism isn't a de jure standard, but even in the worst case, it + // should at least result in an immediate exit. + RAW_LOG(WARNING, "Still here, exiting really ungracefully."); + _exit(signal | (1 << 7)); + } + ExitPosted(); +} + +} // namespace + +void AtomBrowserMainParts::HandleSIGCHLD() { + // We need to accept SIGCHLD, even though our handler is a no-op because + // otherwise we cannot wait on children. (According to POSIX 2001.) + struct sigaction action; + memset(&action, 0, sizeof(action)); + action.sa_handler = SIGCHLDHandler; + CHECK(sigaction(SIGCHLD, &action, NULL) == 0); +} + +void AtomBrowserMainParts::HandleShutdownSignals() { + int pipefd[2]; + int ret = pipe(pipefd); + if (ret < 0) { + PLOG(DFATAL) << "Failed to create pipe"; + } else { + g_pipe_pid = getpid(); + g_shutdown_pipe_read_fd = pipefd[0]; + g_shutdown_pipe_write_fd = pipefd[1]; +#if !defined(ADDRESS_SANITIZER) && !defined(KEEP_SHADOW_STACKS) + const size_t kShutdownDetectorThreadStackSize = PTHREAD_STACK_MIN * 2; +#else + // ASan instrumentation and -finstrument-functions (used for keeping the + // shadow stacks) bloat the stack frames, so we need to increase the stack + // size to avoid hitting the guard page. + const size_t kShutdownDetectorThreadStackSize = PTHREAD_STACK_MIN * 4; +#endif + // TODO(viettrungluu,willchan): crbug.com/29675 - This currently leaks, so + // if you change this, you'll probably need to change the suppression. + if (!base::PlatformThread::CreateNonJoinable( + kShutdownDetectorThreadStackSize, + new ShutdownDetector(g_shutdown_pipe_read_fd))) { + LOG(DFATAL) << "Failed to create shutdown detector task."; + } + } + // Setup signal handlers for shutdown AFTER shutdown pipe is setup because + // it may be called right away after handler is set. + + // If adding to this list of signal handlers, note the new signal probably + // needs to be reset in child processes. See + // base/process_util_posix.cc:LaunchProcess. + + // We need to handle SIGTERM, because that is how many POSIX-based distros ask + // processes to quit gracefully at shutdown time. + struct sigaction action; + memset(&action, 0, sizeof(action)); + action.sa_handler = SIGTERMHandler; + CHECK(sigaction(SIGTERM, &action, NULL) == 0); + // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If + // the browser process is being debugged, GDB will catch the SIGINT first. + action.sa_handler = SIGINTHandler; + CHECK(sigaction(SIGINT, &action, NULL) == 0); + // And SIGHUP, for when the terminal disappears. On shutdown, many Linux + // distros send SIGHUP, SIGTERM, and then SIGKILL. + action.sa_handler = SIGHUPHandler; + CHECK(sigaction(SIGHUP, &action, NULL) == 0); +} + +} // namespace atom diff --git a/filenames.gypi b/filenames.gypi index eb94973e01..04b82992bc 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -125,6 +125,7 @@ 'atom/browser/atom_browser_main_parts.cc', 'atom/browser/atom_browser_main_parts.h', 'atom/browser/atom_browser_main_parts_mac.mm', + 'atom/browser/atom_browser_main_parts_posix.cc', 'atom/browser/atom_javascript_dialog_manager.cc', 'atom/browser/atom_javascript_dialog_manager.h', 'atom/browser/atom_quota_permission_context.cc', From a2a4970f5f6601c6e8b713e6fe342ea63d78b022 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 19:36:41 +0800 Subject: [PATCH 16/56] Fix cpplint warnings --- atom/browser/atom_browser_main_parts_posix.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/atom_browser_main_parts_posix.cc b/atom/browser/atom_browser_main_parts_posix.cc index ea0f87b171..2a0dddc474 100644 --- a/atom/browser/atom_browser_main_parts_posix.cc +++ b/atom/browser/atom_browser_main_parts_posix.cc @@ -171,7 +171,7 @@ void AtomBrowserMainParts::HandleSIGCHLD() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = SIGCHLDHandler; - CHECK(sigaction(SIGCHLD, &action, NULL) == 0); + CHECK_EQ(sigaction(SIGCHLD, &action, NULL), 0); } void AtomBrowserMainParts::HandleShutdownSignals() { @@ -211,15 +211,15 @@ void AtomBrowserMainParts::HandleShutdownSignals() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = SIGTERMHandler; - CHECK(sigaction(SIGTERM, &action, NULL) == 0); + CHECK_EQ(sigaction(SIGTERM, &action, NULL), 0); // Also handle SIGINT - when the user terminates the browser via Ctrl+C. If // the browser process is being debugged, GDB will catch the SIGINT first. action.sa_handler = SIGINTHandler; - CHECK(sigaction(SIGINT, &action, NULL) == 0); + CHECK_EQ(sigaction(SIGINT, &action, NULL), 0); // And SIGHUP, for when the terminal disappears. On shutdown, many Linux // distros send SIGHUP, SIGTERM, and then SIGKILL. action.sa_handler = SIGHUPHandler; - CHECK(sigaction(SIGHUP, &action, NULL) == 0); + CHECK_EQ(sigaction(SIGHUP, &action, NULL), 0); } } // namespace atom From d4bfeff6ad1686feb4a815096bb7890230a73a01 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 20:08:19 +0800 Subject: [PATCH 17/56] Fix crashing on Linux --- atom/browser/atom_browser_main_parts.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/browser/atom_browser_main_parts.cc b/atom/browser/atom_browser_main_parts.cc index e70d42fc76..4c11176997 100644 --- a/atom/browser/atom_browser_main_parts.cc +++ b/atom/browser/atom_browser_main_parts.cc @@ -53,6 +53,7 @@ void AtomBrowserMainParts::RegisterDestructionCallback( } void AtomBrowserMainParts::PreEarlyInitialization() { + brightray::BrowserMainParts::PreEarlyInitialization(); #if defined(OS_POSIX) HandleSIGCHLD(); #endif @@ -119,6 +120,7 @@ void AtomBrowserMainParts::PreMainMessageLoopRun() { } void AtomBrowserMainParts::PostMainMessageLoopStart() { + brightray::BrowserMainParts::PostMainMessageLoopStart(); #if defined(OS_POSIX) HandleShutdownSignals(); #endif From 3d4318e15e757cf26377637ee1240d5b87cde39c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 21:19:44 +0800 Subject: [PATCH 18/56] docs: Remove `cache` and `userCache` dir Closes #1404. --- docs/api/app.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/api/app.md b/docs/api/app.md index e4a8d561e2..0b5780aab7 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -197,12 +197,6 @@ You can request the following paths by the name: * `~/Library/Application Support` on OS X * `userData` The directory for storing your app's configuration files, which by default it is the `appData` directory appended with your app's name. -* `cache` Per-user application cache directory, which by default points to: - * `%APPDATA%` on Windows (which doesn't have a universal cache location) - * `$XDG_CACHE_HOME` or `~/.cache` on Linux - * `~/Library/Caches` on OS X -* `userCache` The directory for placing your app's caches, by default it is the - `cache` directory appended with your app's name. * `temp` Temporary directory. * `userDesktop` The current user's Desktop directory. * `exe` The current executable file. From ca6f6880139670e560157ebaa812cdf73afdeb0a Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 4 Oct 2015 22:19:05 +0800 Subject: [PATCH 19/56] Update brightray for #877 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index bbb9287337..c44f99278b 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit bbb9287337f8b7958b001be35b993c21cd573109 +Subproject commit c44f99278bc4f6823f81b6f3a8d75881d697fd01 From 4d02fc58fa183c13273888cc30a874abaee52238 Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Mon, 5 Oct 2015 03:29:02 +0300 Subject: [PATCH 20/56] Fix restore/unmaximize wrong window size This resolves #2498. --- atom/browser/native_window_views.cc | 46 +++++++++++++++++++---------- atom/browser/native_window_views.h | 6 ++++ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index e9db97e195..7117142cf0 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -283,6 +283,8 @@ NativeWindowViews::NativeWindowViews( else last_window_state_ = ui::SHOW_STATE_NORMAL; + last_normal_size_ = gfx::Size(widget_size_); + if (!has_frame()) { // Set Window style so that we get a minimize and maximize animation when // frameless. @@ -851,23 +853,35 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { NotifyWindowMinimize(); break; case SIZE_RESTORED: - if (last_window_state_ == ui::SHOW_STATE_NORMAL) - return; - - switch (last_window_state_) { - case ui::SHOW_STATE_MAXIMIZED: - last_window_state_ = ui::SHOW_STATE_NORMAL; - NotifyWindowUnmaximize(); - break; - case ui::SHOW_STATE_MINIMIZED: - if (IsFullscreen()) { - last_window_state_ = ui::SHOW_STATE_FULLSCREEN; - NotifyWindowEnterFullScreen(); - } else { + 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; - NotifyWindowRestore(); - } - break; + + // 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; } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 71e122d381..f93a9e2f7f 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -176,6 +176,12 @@ class NativeWindowViews : public NativeWindow, ui::WindowShowState last_window_state_; + // There's an issue with restore on Windows, that sometimes causes the Window + // to receive the wrong size (#2498). To circumvent that, we keep tabs on the + // size of the window while in the normal state (not maximized, minimized or + // fullscreen), so we restore it correctly. + gfx::Size last_normal_size_; + // In charge of running taskbar related APIs. TaskbarHost taskbar_host_; #endif From c34c123b338df7a8a72cc14f0b032eae223800ac Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Mon, 5 Oct 2015 04:01:25 +0300 Subject: [PATCH 21/56] Make it work only on Windows Limiting the solution to Windows only. --- atom/browser/ui/views/frameless_view.cc | 8 ++------ atom/browser/ui/views/win_frame_view.cc | 6 ++++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/atom/browser/ui/views/frameless_view.cc b/atom/browser/ui/views/frameless_view.cc index e8d351ec82..03a31e0828 100644 --- a/atom/browser/ui/views/frameless_view.cc +++ b/atom/browser/ui/views/frameless_view.cc @@ -104,15 +104,11 @@ gfx::Size FramelessView::GetPreferredSize() const { } gfx::Size FramelessView::GetMinimumSize() const { - gfx::Size size = window_->WindowSizeToFramelessSize( - window_->GetMinimumSize()); - return size; + return window_->GetMinimumSize(); } gfx::Size FramelessView::GetMaximumSize() const { - gfx::Size size = window_->WindowSizeToFramelessSize( - window_->GetMaximumSize()); - return size; + return window_->GetMaximumSize(); } const char* FramelessView::GetClassName() const { diff --git a/atom/browser/ui/views/win_frame_view.cc b/atom/browser/ui/views/win_frame_view.cc index db74661932..d0338af19d 100644 --- a/atom/browser/ui/views/win_frame_view.cc +++ b/atom/browser/ui/views/win_frame_view.cc @@ -40,12 +40,14 @@ int WinFrameView::NonClientHitTest(const gfx::Point& point) { } gfx::Size WinFrameView::GetMinimumSize() const { - gfx::Size size = FramelessView::GetMinimumSize(); + gfx::Size size = window_->WindowSizeToFramelessSize( + window_->GetMinimumSize()); return gfx::win::DIPToScreenSize(size); } gfx::Size WinFrameView::GetMaximumSize() const { - gfx::Size size = FramelessView::GetMaximumSize(); + gfx::Size size = window_->WindowSizeToFramelessSize( + window_->GetMaximumSize()); return gfx::win::DIPToScreenSize(size); } From 69140af0835d2d7aea8bbce632ae7fe9faa70bad Mon Sep 17 00:00:00 2001 From: hansrwindhoff Date: Sun, 4 Oct 2015 20:14:52 -0600 Subject: [PATCH 22/56] example code didn't run --- docs/api/screen.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index da15c7326f..9afbf02170 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -37,8 +37,8 @@ app.on('ready', function() { var electronScreen = require('screen'); var displays = electronScreen.getAllDisplays(); var externalDisplay = null; - for (var i in displays) { - if (displays[i].bounds.x > 0 || displays[i].bounds.y > 0) { + for (var i =0; i< displays.length; i++) { + if (displays[i].bounds.x !==0 || displays[i].bounds.y !== 0) { externalDisplay = displays[i]; break; } @@ -48,6 +48,8 @@ app.on('ready', function() { mainWindow = new BrowserWindow({ x: externalDisplay.bounds.x + 50, y: externalDisplay.bounds.y + 50, + width: 900, + height:600 }); } }); From 46c69cc3e5f76aee329a1b79847ac0f65818e5ee Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 11:41:06 +0800 Subject: [PATCH 23/56] docs: Removed unneeded changes from PR --- docs/api/screen.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index 9afbf02170..3b6c276daf 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -37,8 +37,8 @@ app.on('ready', function() { var electronScreen = require('screen'); var displays = electronScreen.getAllDisplays(); var externalDisplay = null; - for (var i =0; i< displays.length; i++) { - if (displays[i].bounds.x !==0 || displays[i].bounds.y !== 0) { + for (var i in displays) { + if (displays[i].bounds.x != 0 || displays[i].bounds.y != 0) { externalDisplay = displays[i]; break; } @@ -48,8 +48,6 @@ app.on('ready', function() { mainWindow = new BrowserWindow({ x: externalDisplay.bounds.x + 50, y: externalDisplay.bounds.y + 50, - width: 900, - height:600 }); } }); From ad8e727ba251b559e48625680a50cc014f26b0e5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 11:41:36 +0800 Subject: [PATCH 24/56] docs: "loaded" event of "process" --- docs/api/process.md | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/api/process.md b/docs/api/process.md index abd3c4fe57..4e0fa4d602 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -9,7 +9,25 @@ upstream node: * `process.versions['chrome']` String - Version of Chromium. * `process.resourcesPath` String - Path to JavaScript source code. -# Methods +## Events + +### Event: 'loaded' + +Emitted when Electron has loaded its internal initialization script and is +beginning to load the web page or the main script. + +It can be used by the preload script to add removed Node global symbols back to +the global scope when node integration is turned off: + +```js +// preload.js +process.once('loaded', function() { + global.setImmediate = setImmediate; + global.clearImmediate = clearImmediate; +}); +``` + +## Methods The `process` object has the following method: @@ -17,7 +35,7 @@ The `process` object has the following method: Causes the main thread of the current process hang. -## process.setFdLimit(maxDescriptors) _OS X_ _Linux_ +### process.setFdLimit(maxDescriptors) _OS X_ _Linux_ * `maxDescriptors` Integer From ec0a8a13219a18989623878ed063449742a42bd6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 11:42:43 +0800 Subject: [PATCH 25/56] Bump v0.33.5 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index b3c9e117a5..637e1c4795 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.33.4', + 'version%': '0.33.5', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index b1b905a433..12934e6ef8 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.33.4 + 0.33.5 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 6d900b0ea0..7a36dcdf35 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,33,4,0 - PRODUCTVERSION 0,33,4,0 + FILEVERSION 0,33,5,0 + PRODUCTVERSION 0,33,5,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.33.4" + VALUE "FileVersion", "0.33.5" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.33.4" + VALUE "ProductVersion", "0.33.5" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 998e430881..42610f196e 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 33 -#define ATOM_PATCH_VERSION 4 +#define ATOM_PATCH_VERSION 5 #define ATOM_VERSION_IS_RELEASE 1 From 7de3aa3cc1eef66a84df8d474954d4e2d81a1adb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 19:57:14 +0800 Subject: [PATCH 26/56] Fix typo, closes #2990 --- atom/browser/native_window_views.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 4282b0eda9..689626fc5f 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -351,7 +351,7 @@ void NativeWindowViews::ShowInactive() { } void NativeWindowViews::Hide() { - web_contents()->WasHidden(); + window_->Hide(); } bool NativeWindowViews::IsVisible() { From 2d676770b12975daf1bbf67d0c758be04e03844f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 19:57:30 +0800 Subject: [PATCH 27/56] Bump v0.33.6 --- atom.gyp | 2 +- atom/browser/resources/mac/Info.plist | 2 +- atom/browser/resources/win/atom.rc | 8 ++++---- atom/common/atom_version.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/atom.gyp b/atom.gyp index 637e1c4795..f06a0c8251 100644 --- a/atom.gyp +++ b/atom.gyp @@ -4,7 +4,7 @@ 'product_name%': 'Electron', 'company_name%': 'GitHub, Inc', 'company_abbr%': 'github', - 'version%': '0.33.5', + 'version%': '0.33.6', }, 'includes': [ 'filenames.gypi', diff --git a/atom/browser/resources/mac/Info.plist b/atom/browser/resources/mac/Info.plist index 12934e6ef8..50e019c1c7 100644 --- a/atom/browser/resources/mac/Info.plist +++ b/atom/browser/resources/mac/Info.plist @@ -17,7 +17,7 @@ CFBundleIconFile atom.icns CFBundleVersion - 0.33.5 + 0.33.6 LSMinimumSystemVersion 10.8.0 NSMainNibFile diff --git a/atom/browser/resources/win/atom.rc b/atom/browser/resources/win/atom.rc index 7a36dcdf35..b1aba451dc 100644 --- a/atom/browser/resources/win/atom.rc +++ b/atom/browser/resources/win/atom.rc @@ -56,8 +56,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,33,5,0 - PRODUCTVERSION 0,33,5,0 + FILEVERSION 0,33,6,0 + PRODUCTVERSION 0,33,6,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -74,12 +74,12 @@ BEGIN BEGIN VALUE "CompanyName", "GitHub, Inc." VALUE "FileDescription", "Electron" - VALUE "FileVersion", "0.33.5" + VALUE "FileVersion", "0.33.6" VALUE "InternalName", "electron.exe" VALUE "LegalCopyright", "Copyright (C) 2015 GitHub, Inc. All rights reserved." VALUE "OriginalFilename", "electron.exe" VALUE "ProductName", "Electron" - VALUE "ProductVersion", "0.33.5" + VALUE "ProductVersion", "0.33.6" VALUE "SquirrelAwareVersion", "1" END END diff --git a/atom/common/atom_version.h b/atom/common/atom_version.h index 42610f196e..8078551b90 100644 --- a/atom/common/atom_version.h +++ b/atom/common/atom_version.h @@ -7,7 +7,7 @@ #define ATOM_MAJOR_VERSION 0 #define ATOM_MINOR_VERSION 33 -#define ATOM_PATCH_VERSION 5 +#define ATOM_PATCH_VERSION 6 #define ATOM_VERSION_IS_RELEASE 1 From 8577f2b52f42335747101123b4fe9e5fa77f1bd8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 16:19:01 +0800 Subject: [PATCH 28/56] osx: Add NativeWindow::SetSizeConstraints --- atom/browser/native_window.cc | 69 +++++++++++++++ atom/browser/native_window.h | 26 ++++-- atom/browser/native_window_mac.h | 12 +-- atom/browser/native_window_mac.mm | 77 +++++++---------- atom/browser/native_window_views.cc | 16 ++++ atom/browser/native_window_views.h | 6 ++ .../browser/app_window/size_constraints.cc | 83 +++++++++++++++++++ .../browser/app_window/size_constraints.h | 57 +++++++++++++ filenames.gypi | 2 + 9 files changed, 287 insertions(+), 61 deletions(-) create mode 100644 chromium_src/extensions/browser/app_window/size_constraints.cc create mode 100644 chromium_src/extensions/browser/app_window/size_constraints.h diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 80a7d1347f..cad6942d2e 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -162,6 +162,14 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } +gfx::Size NativeWindow::ContentSizeToWindowSize(const gfx::Size& size) { + return size; +} + +gfx::Size NativeWindow::WindowSizeToContentSize(const gfx::Size& size) { + return size; +} + void NativeWindow::SetSize(const gfx::Size& size) { SetBounds(gfx::Rect(GetPosition(), size)); } @@ -178,6 +186,67 @@ gfx::Point NativeWindow::GetPosition() { 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) { } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 751644e459..5387833064 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -19,6 +19,7 @@ #include "content/public/browser/readback_types.h" #include "content/public/browser/web_contents_observer.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_skia.h" @@ -110,12 +111,18 @@ class NativeWindow : public base::SupportsUserData, virtual gfx::Size GetSize(); virtual void SetPosition(const gfx::Point& position); virtual gfx::Point GetPosition(); - virtual void SetContentSize(const gfx::Size& size) = 0; - virtual gfx::Size GetContentSize() = 0; - virtual void SetMinimumSize(const gfx::Size& size) = 0; - virtual gfx::Size GetMinimumSize() = 0; - virtual void SetMaximumSize(const gfx::Size& size) = 0; - virtual gfx::Size GetMaximumSize() = 0; + virtual void SetContentSize(const gfx::Size& size); + virtual gfx::Size GetContentSize(); + virtual void SetSizeConstraints( + const extensions::SizeConstraints& size_constraints); + virtual extensions::SizeConstraints GetSizeConstraints(); + 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 bool IsResizable() = 0; virtual void SetAlwaysOnTop(bool top) = 0; @@ -234,6 +241,10 @@ class NativeWindow : public base::SupportsUserData, NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options); + // Converts between content size to window size. + virtual gfx::Size ContentSizeToWindowSize(const gfx::Size& size); + virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size); + // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void BeforeUnloadDialogCancelled() override; @@ -269,6 +280,9 @@ class NativeWindow : public base::SupportsUserData, // has to been explicitly provided. scoped_ptr 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. bool enable_larger_than_screen_; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 20ad605314..60581a2d97 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -44,12 +44,8 @@ class NativeWindowMac : public NativeWindow { bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; - void SetContentSize(const gfx::Size& size) override; - gfx::Size GetContentSize() override; - void SetMinimumSize(const gfx::Size& size) override; - gfx::Size GetMinimumSize() override; - void SetMaximumSize(const gfx::Size& size) override; - gfx::Size GetMaximumSize() override; + void SetContentSizeConstraints( + const extensions::SizeConstraints& size_constraints) override; void SetResizable(bool resizable) override; bool IsResizable() override; void SetAlwaysOnTop(bool top) override; @@ -89,6 +85,10 @@ class NativeWindowMac : public NativeWindow { const content::NativeWebKeyboardEvent&) override; private: + // NativeWindow: + gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override; + gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; + void InstallView(); void UninstallView(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 3e8dab2133..76f9b0d0de 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -22,6 +22,11 @@ namespace { +// Converts gfx::Size to NSSize. +inline NSSize ToNSSize(const gfx::Size& size) { + return NSMakeSize(size.width(), size.height()); +} + // Prevents window from resizing during the scope. class ScopedDisableResize { public: @@ -549,56 +554,18 @@ gfx::Rect NativeWindowMac::GetBounds() { return bounds; } -void NativeWindowMac::SetContentSize(const gfx::Size& size) { - if (!has_frame()) { - SetSize(size); - return; +void NativeWindowMac::SetContentSizeConstraints( + const extensions::SizeConstraints& size_constraints) { + NSView* content = [window_ contentView]; + if (size_constraints.HasMinimumSize()) { + NSSize min_size = ToNSSize(size_constraints.GetMinimumSize()); + [window_ setMinSize:[content convertSize:min_size toView:nil]]; } - - NSRect frame_nsrect = [window_ frame]; - NSSize frame = frame_nsrect.size; - NSSize content = [window_ contentRectForFrameRect:frame_nsrect].size; - - 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); + if (size_constraints.HasMaximumSize()) { + NSSize max_size = ToNSSize(size_constraints.GetMaximumSize()); + [window_ setMaxSize:[content convertSize:max_size toView:nil]]; + } + NativeWindow::SetContentSizeConstraints(size_constraints); } void NativeWindowMac::SetResizable(bool resizable) { @@ -821,6 +788,18 @@ void NativeWindowMac::HandleKeyboardEvent( } } +gfx::Size NativeWindowMac::ContentSizeToWindowSize(const gfx::Size& 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) { + NSRect frame = NSMakeRect(0, 0, size.width(), size.height()); + NSRect content = [window_ contentRectForFrameRect:frame]; + return gfx::Size(content.size); +} + void NativeWindowMac::InstallView() { // Make sure the bottom corner is rounded: http://crbug.com/396264. [[window_ contentView] setWantsLayer:YES]; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index f9e2089a4e..1c7546854e 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -440,6 +440,22 @@ gfx::Rect NativeWindowViews::GetBounds() { return window_->GetWindowBoundsInScreen(); } +void NativeWindowViews::SetSizeConstraints( + const extensions::SizeConstraints& size_constraints) { +} + +extensions::SizeConstraints NativeWindowViews::GetSizeConstraints() { + return extensions::SizeConstraints(); +} + +void NativeWindowViews::SetContentSizeConstraints( + const extensions::SizeConstraints& size_constraints) { +} + +extensions::SizeConstraints NativeWindowViews::GetContentSizeConstraints() { + return extensions::SizeConstraints(); +} + void NativeWindowViews::SetContentSize(const gfx::Size& size) { if (!has_frame()) { NativeWindow::SetSize(size); diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 2b2322f195..5a90e6a221 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -63,6 +63,12 @@ class NativeWindowViews : public NativeWindow, bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; + void SetSizeConstraints( + const extensions::SizeConstraints& size_constraints) override; + extensions::SizeConstraints GetSizeConstraints() override; + void SetContentSizeConstraints( + const extensions::SizeConstraints& size_constraints) override; + extensions::SizeConstraints GetContentSizeConstraints() override; void SetContentSize(const gfx::Size& size) override; gfx::Size GetContentSize() override; void SetMinimumSize(const gfx::Size& size) override; diff --git a/chromium_src/extensions/browser/app_window/size_constraints.cc b/chromium_src/extensions/browser/app_window/size_constraints.cc new file mode 100644 index 0000000000..6d248c1601 --- /dev/null +++ b/chromium_src/extensions/browser/app_window/size_constraints.cc @@ -0,0 +1,83 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/browser/app_window/size_constraints.h" + +#include + +#include "ui/gfx/geometry/insets.h" + +namespace extensions { + +SizeConstraints::SizeConstraints() + : maximum_size_(kUnboundedSize, kUnboundedSize) {} + +SizeConstraints::SizeConstraints(const gfx::Size& min_size, + const gfx::Size& max_size) + : minimum_size_(min_size), maximum_size_(max_size) {} + +SizeConstraints::~SizeConstraints() {} + +// static +gfx::Size SizeConstraints::AddFrameToConstraints( + const gfx::Size& size_constraints, + const gfx::Insets& frame_insets) { + return gfx::Size( + size_constraints.width() == kUnboundedSize + ? kUnboundedSize + : size_constraints.width() + frame_insets.width(), + size_constraints.height() == kUnboundedSize + ? kUnboundedSize + : size_constraints.height() + frame_insets.height()); +} + +gfx::Size SizeConstraints::ClampSize(gfx::Size size) const { + const gfx::Size max_size = GetMaximumSize(); + if (max_size.width() != kUnboundedSize) + size.set_width(std::min(size.width(), max_size.width())); + if (max_size.height() != kUnboundedSize) + size.set_height(std::min(size.height(), max_size.height())); + size.SetToMax(GetMinimumSize()); + return size; +} + +bool SizeConstraints::HasMinimumSize() const { + const gfx::Size min_size = GetMinimumSize(); + return min_size.width() != kUnboundedSize || + min_size.height() != kUnboundedSize; +} + +bool SizeConstraints::HasMaximumSize() const { + const gfx::Size max_size = GetMaximumSize(); + return max_size.width() != kUnboundedSize || + max_size.height() != kUnboundedSize; +} + +bool SizeConstraints::HasFixedSize() const { + return !GetMinimumSize().IsEmpty() && GetMinimumSize() == GetMaximumSize(); +} + +gfx::Size SizeConstraints::GetMinimumSize() const { + return minimum_size_; +} + +gfx::Size SizeConstraints::GetMaximumSize() const { + return gfx::Size( + maximum_size_.width() == kUnboundedSize + ? kUnboundedSize + : std::max(maximum_size_.width(), minimum_size_.width()), + maximum_size_.height() == kUnboundedSize + ? kUnboundedSize + : std::max(maximum_size_.height(), minimum_size_.height())); +} + +void SizeConstraints::set_minimum_size(const gfx::Size& min_size) { + minimum_size_ = min_size; +} + +void SizeConstraints::set_maximum_size(const gfx::Size& max_size) { + maximum_size_ = max_size; +} + +} // namespace extensions diff --git a/chromium_src/extensions/browser/app_window/size_constraints.h b/chromium_src/extensions/browser/app_window/size_constraints.h new file mode 100644 index 0000000000..ecacf1e5eb --- /dev/null +++ b/chromium_src/extensions/browser/app_window/size_constraints.h @@ -0,0 +1,57 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef EXTENSIONS_BROWSER_APP_WINDOW_SIZE_CONSTRAINTS_H_ +#define EXTENSIONS_BROWSER_APP_WINDOW_SIZE_CONSTRAINTS_H_ + +#include "ui/gfx/geometry/size.h" + +namespace gfx { +class Insets; +} + +namespace extensions { + +class SizeConstraints { + public: + // The value SizeConstraints uses to represent an unbounded width or height. + // This is an enum so that it can be declared inline here. + enum { kUnboundedSize = 0 }; + + SizeConstraints(); + SizeConstraints(const gfx::Size& min_size, const gfx::Size& max_size); + ~SizeConstraints(); + + // Adds frame insets to a size constraint. + static gfx::Size AddFrameToConstraints(const gfx::Size& size_constraints, + const gfx::Insets& frame_insets); + + // Returns the bounds with its size clamped to the min/max size. + gfx::Size ClampSize(gfx::Size size) const; + + // When gfx::Size is used as a min/max size, a zero represents an unbounded + // component. This method checks whether either component is specified. + // Note we can't use gfx::Size::IsEmpty as it returns true if either width + // or height is zero. + bool HasMinimumSize() const; + bool HasMaximumSize() const; + + // This returns true if all components are specified, and min and max are + // equal. + bool HasFixedSize() const; + + gfx::Size GetMaximumSize() const; + gfx::Size GetMinimumSize() const; + + void set_minimum_size(const gfx::Size& min_size); + void set_maximum_size(const gfx::Size& max_size); + + private: + gfx::Size minimum_size_; + gfx::Size maximum_size_; +}; + +} // namespace extensions + +#endif // EXTENSIONS_BROWSER_APP_WINDOW_SIZE_CONSTRAINTS_H_ diff --git a/filenames.gypi b/filenames.gypi index 04b82992bc..a6e799cd67 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -429,6 +429,8 @@ 'chromium_src/chrome/renderer/tts_dispatcher.cc', 'chromium_src/chrome/renderer/tts_dispatcher.h', 'chromium_src/chrome/utility/utility_message_handler.h', + 'chromium_src/extensions/browser/app_window/size_constraints.cc', + 'chromium_src/extensions/browser/app_window/size_constraints.h', 'chromium_src/library_loaders/libspeechd_loader.cc', 'chromium_src/library_loaders/libspeechd.h', 'chromium_src/net/test/embedded_test_server/stream_listen_socket.cc', From a76ea00249286b791a3308230ea7179516ef38d0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 19:05:59 +0800 Subject: [PATCH 29/56] views: Implement NativeWindow::SetSizeConstraints --- atom/browser/native_window_views.cc | 139 +++++++++------------ atom/browser/native_window_views.h | 22 +--- atom/browser/ui/views/frameless_view.cc | 4 +- atom/browser/ui/views/native_frame_view.cc | 5 +- atom/browser/ui/views/native_frame_view.h | 6 +- atom/browser/ui/views/win_frame_view.cc | 4 +- 6 files changed, 71 insertions(+), 109 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 1c7546854e..fdcbe42205 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -186,7 +186,8 @@ NativeWindowViews::NativeWindowViews( // will not allow us to resize the window larger than scree. // Setting directly to INT_MAX somehow doesn't work, so we just devide // by 10, which should still be large enough. - maximum_size_.SetSize(INT_MAX / 10, INT_MAX / 10); + SetContentSizeConstraints(extensions::SizeConstraints( + gfx::Size(), gfx::Size(INT_MAX / 10, INT_MAX / 10))); int width = 800, height = 600; options.Get(switches::kWidth, &width); @@ -271,11 +272,6 @@ NativeWindowViews::NativeWindowViews( set_background(views::Background::CreateStandardPanelBackground()); AddChildView(web_view_); - if (has_frame() && - options.Get(switches::kUseContentSize, &use_content_size_) && - use_content_size_) - bounds = ContentBoundsToWindowBounds(bounds); - #if defined(OS_WIN) // Save initial window state. if (fullscreen) @@ -316,8 +312,14 @@ NativeWindowViews::NativeWindowViews( if (transparent() && !has_frame()) 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_->CenterWindow(bounds.size()); + window_->CenterWindow(size); Layout(); } @@ -440,60 +442,6 @@ gfx::Rect NativeWindowViews::GetBounds() { return window_->GetWindowBoundsInScreen(); } -void NativeWindowViews::SetSizeConstraints( - const extensions::SizeConstraints& size_constraints) { -} - -extensions::SizeConstraints NativeWindowViews::GetSizeConstraints() { - return extensions::SizeConstraints(); -} - -void NativeWindowViews::SetContentSizeConstraints( - const extensions::SizeConstraints& size_constraints) { -} - -extensions::SizeConstraints NativeWindowViews::GetContentSizeConstraints() { - return extensions::SizeConstraints(); -} - -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() { - if (!has_frame()) - return GetSize(); - - gfx::Size content_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) { - minimum_size_ = size; -} - -gfx::Size NativeWindowViews::GetMinimumSize() { - return minimum_size_; -} - -void NativeWindowViews::SetMaximumSize(const gfx::Size& size) { - maximum_size_ = size; -} - -gfx::Size NativeWindowViews::GetMaximumSize() { - return maximum_size_; -} - void NativeWindowViews::SetResizable(bool resizable) { #if defined(OS_WIN) // WS_MAXIMIZEBOX => Maximize button @@ -929,6 +877,47 @@ gfx::Size NativeWindowViews::WindowSizeToFramelessSize( return window_bounds.size(); } +gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) { + if (!has_frame()) + return size; + + gfx::Size window_size(size); +#if defined(OS_WIN) + gfx::Rect dpi_bounds = + gfx::Rect(gfx::Point(), gfx::win::DIPToScreenSize(size)); + gfx::Rect window_bounds = gfx::win::ScreenToDIPRect( + window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds)); + window_size = window_bounds.size(); +#endif + + 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( content::WebContents*, const content::NativeWebKeyboardEvent& event) { @@ -970,6 +959,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) { return accelerator_util::TriggerAcceleratorTableCommand( &accelerator_table_, accelerator); @@ -992,26 +989,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() { if (IsMaximized()) return ui::SHOW_STATE_MAXIMIZED; diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 5a90e6a221..0e74410868 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -63,18 +63,6 @@ class NativeWindowViews : public NativeWindow, bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; - void SetSizeConstraints( - const extensions::SizeConstraints& size_constraints) override; - extensions::SizeConstraints GetSizeConstraints() override; - void SetContentSizeConstraints( - const extensions::SizeConstraints& size_constraints) override; - extensions::SizeConstraints GetContentSizeConstraints() override; - void SetContentSize(const gfx::Size& size) override; - gfx::Size GetContentSize() override; - void SetMinimumSize(const gfx::Size& size) override; - gfx::Size GetMinimumSize() override; - void SetMaximumSize(const gfx::Size& size) override; - gfx::Size GetMaximumSize() override; void SetResizable(bool resizable) override; bool IsResizable() override; void SetAlwaysOnTop(bool top) override; @@ -148,20 +136,20 @@ class NativeWindowViews : public NativeWindow, #endif // NativeWindow: + gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override; + gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; void HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) override; // views::View: + gfx::Size GetMinimumSize() override; + gfx::Size GetMaximumSize() override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; // Register accelerators supported by the 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. ui::WindowShowState GetRestoredState(); @@ -203,8 +191,6 @@ class NativeWindowViews : public NativeWindow, bool use_content_size_; bool resizable_; std::string title_; - gfx::Size minimum_size_; - gfx::Size maximum_size_; gfx::Size widget_size_; DISALLOW_COPY_AND_ASSIGN(NativeWindowViews); diff --git a/atom/browser/ui/views/frameless_view.cc b/atom/browser/ui/views/frameless_view.cc index 03a31e0828..f5e28025e9 100644 --- a/atom/browser/ui/views/frameless_view.cc +++ b/atom/browser/ui/views/frameless_view.cc @@ -104,11 +104,11 @@ gfx::Size FramelessView::GetPreferredSize() const { } gfx::Size FramelessView::GetMinimumSize() const { - return window_->GetMinimumSize(); + return static_cast(window_)->GetMinimumSize(); } gfx::Size FramelessView::GetMaximumSize() const { - return window_->GetMaximumSize(); + return static_cast(window_)->GetMaximumSize(); } const char* FramelessView::GetClassName() const { diff --git a/atom/browser/ui/views/native_frame_view.cc b/atom/browser/ui/views/native_frame_view.cc index a434fb4349..134255f484 100644 --- a/atom/browser/ui/views/native_frame_view.cc +++ b/atom/browser/ui/views/native_frame_view.cc @@ -4,7 +4,7 @@ #include "atom/browser/ui/views/native_frame_view.h" -#include "atom/browser/native_window_views.h" +#include "atom/browser/native_window.h" namespace atom { @@ -14,8 +14,7 @@ const char kViewClassName[] = "AtomNativeFrameView"; } // namespace -NativeFrameView::NativeFrameView(NativeWindowViews* window, - views::Widget* widget) +NativeFrameView::NativeFrameView(NativeWindow* window, views::Widget* widget) : views::NativeFrameView(widget), window_(window) { } diff --git a/atom/browser/ui/views/native_frame_view.h b/atom/browser/ui/views/native_frame_view.h index acbe9cddc8..670459f1cb 100644 --- a/atom/browser/ui/views/native_frame_view.h +++ b/atom/browser/ui/views/native_frame_view.h @@ -9,13 +9,13 @@ namespace atom { -class NativeWindowViews; +class NativeWindow; // Like the views::NativeFrameView, but returns the min/max size from the // NativeWindowViews. class NativeFrameView : public views::NativeFrameView { public: - NativeFrameView(NativeWindowViews* window, views::Widget* widget); + NativeFrameView(NativeWindow* window, views::Widget* widget); protected: // views::View: @@ -24,7 +24,7 @@ class NativeFrameView : public views::NativeFrameView { const char* GetClassName() const override; private: - NativeWindowViews* window_; // weak ref. + NativeWindow* window_; // weak ref. DISALLOW_COPY_AND_ASSIGN(NativeFrameView); }; diff --git a/atom/browser/ui/views/win_frame_view.cc b/atom/browser/ui/views/win_frame_view.cc index d0338af19d..7106d8f759 100644 --- a/atom/browser/ui/views/win_frame_view.cc +++ b/atom/browser/ui/views/win_frame_view.cc @@ -41,13 +41,13 @@ int WinFrameView::NonClientHitTest(const gfx::Point& point) { gfx::Size WinFrameView::GetMinimumSize() const { gfx::Size size = window_->WindowSizeToFramelessSize( - window_->GetMinimumSize()); + FramelessView::GetMinimumSize()); return gfx::win::DIPToScreenSize(size); } gfx::Size WinFrameView::GetMaximumSize() const { gfx::Size size = window_->WindowSizeToFramelessSize( - window_->GetMaximumSize()); + FramelessView::GetMaximumSize()); return gfx::win::DIPToScreenSize(size); } From 279407f7a300e0914b5fdc6b0b6cb0fb3b23a2f8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 19:32:23 +0800 Subject: [PATCH 30/56] osx: Fix converting size for frameless window --- atom/browser/native_window_mac.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 76f9b0d0de..70c3cfc0cc 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -789,12 +789,18 @@ void NativeWindowMac::HandleKeyboardEvent( } 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); From a9b0111c3e312d5797d1d4e5e64447f50e856467 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 20:03:43 +0800 Subject: [PATCH 31/56] views: Use the quicker way of return content size Converting content size to window size on high DPI systems will lose percise and have 1px offset sometimes. --- atom/browser/native_window_views.cc | 4 ++++ atom/browser/native_window_views.h | 1 + 2 files changed, 5 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index fdcbe42205..0264ac59e1 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -442,6 +442,10 @@ gfx::Rect NativeWindowViews::GetBounds() { return window_->GetWindowBoundsInScreen(); } +gfx::Size NativeWindowViews::GetContentSize() { + return web_view_->size(); +} + void NativeWindowViews::SetResizable(bool resizable) { #if defined(OS_WIN) // WS_MAXIMIZEBOX => Maximize button diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 0e74410868..1ba02e89a3 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -63,6 +63,7 @@ class NativeWindowViews : public NativeWindow, bool IsFullscreen() const override; void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; + gfx::Size GetContentSize() override; void SetResizable(bool resizable) override; bool IsResizable() override; void SetAlwaysOnTop(bool top) override; From d19ead1907acbbf60b069f25709562d66cf6aad8 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 20:09:29 +0800 Subject: [PATCH 32/56] osx: Call setContentMinSize in SetContentSizeConstraints --- atom/browser/native_window_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 70c3cfc0cc..bb00a82451 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -559,11 +559,11 @@ void NativeWindowMac::SetContentSizeConstraints( NSView* content = [window_ contentView]; if (size_constraints.HasMinimumSize()) { NSSize min_size = ToNSSize(size_constraints.GetMinimumSize()); - [window_ setMinSize:[content convertSize:min_size toView:nil]]; + [window_ setContentMinSize:[content convertSize:min_size toView:nil]]; } if (size_constraints.HasMaximumSize()) { NSSize max_size = ToNSSize(size_constraints.GetMaximumSize()); - [window_ setMaxSize:[content convertSize:max_size toView:nil]]; + [window_ setContentMaxSize:[content convertSize:max_size toView:nil]]; } NativeWindow::SetContentSizeConstraints(size_constraints); } From e675407552c808a43dea74ad8796cd0fa9d8c05e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 20:36:28 +0800 Subject: [PATCH 33/56] Make min/max size respect use-content-size --- atom/browser/native_window.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index cad6942d2e..f8023222fb 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -119,15 +119,23 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { } else if (options.Get(switches::kCenter, ¢er) && center) { Center(); } + extensions::SizeConstraints size_constraints; int min_height = 0, min_width = 0; if (options.Get(switches::kMinHeight, &min_height) | options.Get(switches::kMinWidth, &min_width)) { - SetMinimumSize(gfx::Size(min_width, min_height)); + size_constraints.set_minimum_size(gfx::Size(min_width, min_height)); } int max_height = INT_MAX, max_width = INT_MAX; if (options.Get(switches::kMaxHeight, &max_height) | 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); } bool resizable; if (options.Get(switches::kResizable, &resizable)) { From 3b1ee994e21f5afc361c830913bce175a37a6217 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 20:37:08 +0800 Subject: [PATCH 34/56] views: Remove hack on setting min/max size for frameless window --- atom/browser/native_window_views.cc | 27 ------------------------- atom/browser/native_window_views.h | 2 -- atom/browser/ui/views/frameless_view.cc | 4 ++-- atom/browser/ui/views/win_frame_view.cc | 13 ------------ atom/browser/ui/views/win_frame_view.h | 2 -- 5 files changed, 2 insertions(+), 46 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 0264ac59e1..5cd99dbdef 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -854,33 +854,6 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { } #endif -gfx::Size NativeWindowViews::WindowSizeToFramelessSize( - const gfx::Size& size) { - if (size.width() == 0 && size.height() == 0) - return size; - - gfx::Rect window_bounds = gfx::Rect(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) - gfx::Size frame_size = gfx::win::ScreenToDIPRect( - window_->non_client_view()->GetWindowBoundsForClientBounds( - gfx::Rect())).size(); -#else - gfx::Size frame_size = - window_->non_client_view()->GetWindowBoundsForClientBounds( - gfx::Rect()).size(); -#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(); -} - gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) { if (!has_frame()) return size; diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 1ba02e89a3..35ca7b63e2 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -89,8 +89,6 @@ class NativeWindowViews : public NativeWindow, gfx::AcceleratedWidget GetAcceleratedWidget(); - gfx::Size WindowSizeToFramelessSize(const gfx::Size& size); - views::Widget* widget() const { return window_.get(); } #if defined(OS_WIN) diff --git a/atom/browser/ui/views/frameless_view.cc b/atom/browser/ui/views/frameless_view.cc index f5e28025e9..2ec4459f6b 100644 --- a/atom/browser/ui/views/frameless_view.cc +++ b/atom/browser/ui/views/frameless_view.cc @@ -104,11 +104,11 @@ gfx::Size FramelessView::GetPreferredSize() const { } gfx::Size FramelessView::GetMinimumSize() const { - return static_cast(window_)->GetMinimumSize(); + return window_->GetContentSizeConstraints().GetMinimumSize(); } gfx::Size FramelessView::GetMaximumSize() const { - return static_cast(window_)->GetMaximumSize(); + return window_->GetContentSizeConstraints().GetMaximumSize(); } const char* FramelessView::GetClassName() const { diff --git a/atom/browser/ui/views/win_frame_view.cc b/atom/browser/ui/views/win_frame_view.cc index 7106d8f759..fca7cb2334 100644 --- a/atom/browser/ui/views/win_frame_view.cc +++ b/atom/browser/ui/views/win_frame_view.cc @@ -5,7 +5,6 @@ #include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/native_window_views.h" -#include "ui/gfx/win/dpi.h" #include "ui/views/widget/widget.h" #include "ui/views/win/hwnd_util.h" @@ -39,18 +38,6 @@ int WinFrameView::NonClientHitTest(const gfx::Point& point) { return FramelessView::NonClientHitTest(point); } -gfx::Size WinFrameView::GetMinimumSize() const { - gfx::Size size = window_->WindowSizeToFramelessSize( - FramelessView::GetMinimumSize()); - return gfx::win::DIPToScreenSize(size); -} - -gfx::Size WinFrameView::GetMaximumSize() const { - gfx::Size size = window_->WindowSizeToFramelessSize( - FramelessView::GetMaximumSize()); - return gfx::win::DIPToScreenSize(size); -} - const char* WinFrameView::GetClassName() const { return kViewClassName; } diff --git a/atom/browser/ui/views/win_frame_view.h b/atom/browser/ui/views/win_frame_view.h index 825677bff3..b2c1ef3a15 100644 --- a/atom/browser/ui/views/win_frame_view.h +++ b/atom/browser/ui/views/win_frame_view.h @@ -20,8 +20,6 @@ class WinFrameView : public FramelessView { int NonClientHitTest(const gfx::Point& point) override; // views::View: - gfx::Size GetMinimumSize() const override; - gfx::Size GetMaximumSize() const override; const char* GetClassName() const override; private: From 857acd25741969d390dec96a23ad65a01fdd93a1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 5 Oct 2015 21:06:57 +0800 Subject: [PATCH 35/56] win: Fix GetContentSize for minimized window --- atom/browser/native_window_views.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 5cd99dbdef..d7d6cf8add 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -443,6 +443,11 @@ gfx::Rect NativeWindowViews::GetBounds() { } gfx::Size NativeWindowViews::GetContentSize() { +#if defined(OS_WIN) + if (IsMinimized()) + return NativeWindow::GetContentSize(); +#endif + return web_view_->size(); } From 239b97cde16896e127d1f814549e26ee474a4abf Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Mon, 5 Oct 2015 16:51:49 +0300 Subject: [PATCH 36/56] Update process.md Fixed the `loaded` example according to [this](https://github.com/atom/electron/issues/2984#issuecomment-145465907) comment. --- docs/api/process.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/process.md b/docs/api/process.md index 4e0fa4d602..a2157886bc 100644 --- a/docs/api/process.md +++ b/docs/api/process.md @@ -21,9 +21,11 @@ the global scope when node integration is turned off: ```js // preload.js +var _setImmediate = setImmediate; +var _clearImmediate = clearImmediate; process.once('loaded', function() { - global.setImmediate = setImmediate; - global.clearImmediate = clearImmediate; + global.setImmediate = _setImmediate; + global.clearImmediate = _clearImmediate; }); ``` From ea3e84e7ff38393449c70e447019342766836e2d Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Mon, 5 Oct 2015 16:56:36 +0300 Subject: [PATCH 37/56] Update screen.md Removed a trailing comma. --- docs/api/screen.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/screen.md b/docs/api/screen.md index 3b6c276daf..42468da160 100644 --- a/docs/api/screen.md +++ b/docs/api/screen.md @@ -47,7 +47,7 @@ app.on('ready', function() { if (externalDisplay) { mainWindow = new BrowserWindow({ x: externalDisplay.bounds.x + 50, - y: externalDisplay.bounds.y + 50, + y: externalDisplay.bounds.y + 50 }); } }); From 87e0c812e9de44c96b33a65432decbd012c2d17a Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Mon, 5 Oct 2015 17:48:48 +0300 Subject: [PATCH 38/56] Update native modules doc --- docs/tutorial/using-native-node-modules.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/tutorial/using-native-node-modules.md b/docs/tutorial/using-native-node-modules.md index 0e6477fc4c..491415b900 100644 --- a/docs/tutorial/using-native-node-modules.md +++ b/docs/tutorial/using-native-node-modules.md @@ -6,16 +6,17 @@ the location of Electron's headers when building native modules. ## Native Node Module Compatibility -Since Node v0.11.x there were vital changes in the V8 API. So generally all -native modules written for Node v0.10.x won't work for newer Node or io.js -versions. And because Electron internally uses __io.js v3.1.0__, it has the -same problem. +Native modules might break when Node starts using a new version of V8. +To make sure the module you're interested in will work with Electron, you should +check if it supports the internal Node version used by Electron. +You can check what version of Node is used in Electron by looking it up in +the [releases](https://github.com/atom/electron/releases) page or by using +`process.version` (see [Quick Start](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md) +for example). -To solve this, you should use modules that support Node v0.11.x or later, -[many modules](https://www.npmjs.org/browse/depended/nan) do support both now. -For old modules that only support Node v0.10.x, you should use the -[nan](https://github.com/rvagg/nan) module to port it to v0.11.x or later -versions of Node or io.js. +Consider using [NAN](https://github.com/nodejs/nan/) for your own modules, since +it makes it easier to support multiple versions of Node. It's also helpful for +porting old modules to newer versions of Node so they can work with Electron. ## How to Install Native Modules From bb4951514582b366a91b4367158e710f5cc1eee0 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 00:13:57 +0800 Subject: [PATCH 39/56] Separate Windows specific code of NativeWindow to another file --- atom/browser/native_window_views.cc | 136 ---------------------- atom/browser/native_window_views_win.cc | 145 ++++++++++++++++++++++++ filenames.gypi | 1 + 3 files changed, 146 insertions(+), 136 deletions(-) create mode 100644 atom/browser/native_window_views_win.cc diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index d7d6cf8add..308e8ee3dc 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -77,70 +77,6 @@ bool IsAltModifier(const content::NativeWebKeyboardEvent& event) { (modifiers == (Modifiers::AltKey | Modifiers::IsRight)); } -#if defined(OS_WIN) -// 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"; - } -} -#endif - class NativeWindowClientView : public views::ClientView { public: NativeWindowClientView(views::Widget* widget, @@ -787,78 +723,6 @@ void NativeWindowViews::OnWidgetMove() { NotifyWindowMove(); } -#if defined(OS_WIN) -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) { - 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::ContentSizeToWindowSize(const gfx::Size& size) { if (!has_frame()) return size; diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc new file mode 100644 index 0000000000..79c5128943 --- /dev/null +++ b/atom/browser/native_window_views_win.cc @@ -0,0 +1,145 @@ +// 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" + +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) { + 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. + 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. + SetSize(last_normal_size_); + + NotifyWindowRestore(); + } + break; + } + } + break; + } +} + +} // namespace atom diff --git a/filenames.gypi b/filenames.gypi index a6e799cd67..6418ba2872 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -154,6 +154,7 @@ 'atom/browser/mac/atom_application_delegate.mm', 'atom/browser/native_window.cc', 'atom/browser/native_window.h', + 'atom/browser/native_window_views_win.cc', 'atom/browser/native_window_views.cc', 'atom/browser/native_window_views.h', 'atom/browser/native_window_mac.h', From 60fb406c614af764b21df19ff1cc654ee2c1edda Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 00:15:10 +0800 Subject: [PATCH 40/56] views: Fix content size constraints in window with menubar --- atom/browser/native_window_views.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 308e8ee3dc..0e04414b6a 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -519,8 +519,24 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) { if (!menu_bar_autohide_) { 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); + } } } From c8723238f8fc6abb68ad42a3f9411760e1fcd048 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 00:21:37 +0800 Subject: [PATCH 41/56] win: Fix building on Windows --- atom/browser/native_window_views_win.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/native_window_views_win.cc b/atom/browser/native_window_views_win.cc index 79c5128943..6092a2242a 100644 --- a/atom/browser/native_window_views_win.cc +++ b/atom/browser/native_window_views_win.cc @@ -118,7 +118,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { // When the window is restored we resize it to the previous known // normal size. - SetSize(last_normal_size_); + NativeWindow::SetSize(last_normal_size_); NotifyWindowUnmaximize(); break; @@ -131,7 +131,7 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) { // When the window is restored we resize it to the previous known // normal size. - SetSize(last_normal_size_); + NativeWindow::SetSize(last_normal_size_); NotifyWindowRestore(); } From b70e7c6a4cc51548769075f3f9925430e2435746 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 00:39:16 +0800 Subject: [PATCH 42/56] Remove default definition of ContentSizeToWindowSize --- atom/browser/native_window.cc | 8 -------- atom/browser/native_window.h | 4 ++-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index f8023222fb..641bdd3757 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -170,14 +170,6 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } -gfx::Size NativeWindow::ContentSizeToWindowSize(const gfx::Size& size) { - return size; -} - -gfx::Size NativeWindow::WindowSizeToContentSize(const gfx::Size& size) { - return size; -} - void NativeWindow::SetSize(const gfx::Size& size) { SetBounds(gfx::Rect(GetPosition(), size)); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 5387833064..379c23837b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -242,8 +242,8 @@ class NativeWindow : public base::SupportsUserData, const mate::Dictionary& options); // Converts between content size to window size. - virtual gfx::Size ContentSizeToWindowSize(const gfx::Size& size); - virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size); + virtual gfx::Size ContentSizeToWindowSize(const gfx::Size& size) = 0; + virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size) = 0; // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; From ccf4ed907a2ad95bcbb35925ec9ddf59195605a6 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Mon, 5 Oct 2015 19:11:20 +0200 Subject: [PATCH 43/56] Fix some minor bugs related to KeyboardEvent sending --- atom/common/keyboad_util.cc | 7 ++++--- atom/common/native_mate_converters/blink_converter.cc | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/atom/common/keyboad_util.cc b/atom/common/keyboad_util.cc index 1baa829ff7..29d1a800c8 100644 --- a/atom/common/keyboad_util.cc +++ b/atom/common/keyboad_util.cc @@ -10,9 +10,10 @@ namespace atom { ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) { *shifted = false; switch (c) { - case 8: case 0x7F: return ui::VKEY_BACK; - case 9: return ui::VKEY_TAB; - case 0xD: case 3: return ui::VKEY_RETURN; + case 0x08: return ui::VKEY_BACK; + case 0x7F: return ui::VKEY_DELETE; + case 0x09: return ui::VKEY_TAB; + case 0x0D: return ui::VKEY_RETURN; case 0x1B: return ui::VKEY_ESCAPE; case ' ': return ui::VKEY_SPACE; diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 0a599bfdf0..fcfc8905b3 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -61,7 +61,7 @@ struct Converter { else if (type == "mousewheel") *out = blink::WebInputEvent::MouseWheel; else if (type == "keydown") - *out = blink::WebInputEvent::KeyDown; + *out = blink::WebInputEvent::RawKeyDown; else if (type == "keyup") *out = blink::WebInputEvent::KeyUp; else if (type == "char") From c3cd438d34a265074c2896a688811d5f71f6d60a Mon Sep 17 00:00:00 2001 From: Eran Tiktin Date: Mon, 5 Oct 2015 21:12:29 +0300 Subject: [PATCH 44/56] Replace io.js references with node.js references --- README.md | 2 +- docs/api/native-image.md | 2 +- docs/tutorial/quick-start.md | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fa122c9b6c..94d4c09982 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ :zap: *Formerly known as Atom Shell* :zap: 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 editor](https://github.com/atom/atom). diff --git a/docs/api/native-image.md b/docs/api/native-image.md index df2bb96ff9..097a8130c2 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -142,7 +142,7 @@ Returns a boolean whether the image is empty. Returns the size of the image. -[buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer +[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer ### `image.setTemplateImage(option)` diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index 94368df09c..5300d754a6 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -2,7 +2,7 @@ Electron enables you to create desktop applications with pure JavaScript by providing a runtime with rich native (operating system) APIs. You could see it -as a variant of the io.js runtime that is focused on desktop applications +as a variant of the Node.js runtime that is focused on desktop applications instead of web servers. This doesn't mean Electron is a JavaScript binding to graphical user interface @@ -22,8 +22,9 @@ multi-process architecture is also used. Each web page in Electron runs in its own process, which is called __the renderer process__. In normal browsers, web pages usually run in a sandboxed environment and are not -allowed access to native resources. Electron users, however, have the power to use -io.js APIs in web pages allowing lower level operating system interactions. +allowed access to native resources. Electron users, however, have the power to +use Node.js APIs in web pages allowing lower level operating system +interactions. ### Differences Between Main Process and Renderer Process @@ -129,7 +130,7 @@ Finally the `index.html` is the web page you want to show:

Hello World!

- We are using io.js + We are using Node.js and Electron . From db46c1b92561a7145ff1920de1b49c085cc2d380 Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 6 Oct 2015 13:48:39 +0900 Subject: [PATCH 45/56] Update as upstream --- docs-translations/ko-KR/api/process.md | 16 ++++++++++++++++ docs-translations/ko-KR/api/screen.md | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/docs-translations/ko-KR/api/process.md b/docs-translations/ko-KR/api/process.md index f557f8cc6b..57ba0fa768 100644 --- a/docs-translations/ko-KR/api/process.md +++ b/docs-translations/ko-KR/api/process.md @@ -7,6 +7,22 @@ Electron의 `process` 객체는 기존의 node와는 달리 약간의 차이점 * `process.versions['chrome']` String - Chromium의 버전. * `process.resourcesPath` String - JavaScript 소스코드의 경로. +## Events + +### Event: 'loaded' + +Electron 내부 초기화 스크립트의 로드가 완료되고, 웹 페이지나 메인 스크립트를 로드하기 시작할 때 발생하는 이벤트입니다. + +이 이벤트는 preload 스크립트를 통해 node 통합이 꺼져있는 전역 스코프에 node의 전역 심볼들을 다시 추가할 때 사용할 수 있습니다: + +```javascript +// preload.js +process.once('loaded', function() { + global.setImmediate = setImmediate; + global.clearImmediate = clearImmediate; +}); +``` + ## Methods `process` 객체는 다음과 같은 메서드를 가지고 있습니다: diff --git a/docs-translations/ko-KR/api/screen.md b/docs-translations/ko-KR/api/screen.md index 2d3c02f854..de2d8baf4e 100644 --- a/docs-translations/ko-KR/api/screen.md +++ b/docs-translations/ko-KR/api/screen.md @@ -36,7 +36,7 @@ app.on('ready', function() { var displays = electronScreen.getAllDisplays(); var externalDisplay = null; for (var i in displays) { - if (displays[i].bounds.x > 0 || displays[i].bounds.y > 0) { + if (displays[i].bounds.x != 0 || displays[i].bounds.y != 0) { externalDisplay = displays[i]; break; } From 428c5b6d01fb0cc7aaa465ca98832d395e16e2b2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 14:50:18 +0800 Subject: [PATCH 46/56] Setting "x" and "y" should not change window size --- atom/browser/native_window.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 641bdd3757..981804cb22 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -112,10 +112,7 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { int x = -1, y = -1; bool center; if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) { - int width = -1, height = -1; - options.Get(switches::kWidth, &width); - options.Get(switches::kHeight, &height); - SetBounds(gfx::Rect(x, y, width, height)); + SetPosition(gfx::Point(x, y)); } else if (options.Get(switches::kCenter, ¢er) && center) { Center(); } From 6fea6cf58acbc00a66837628d3a20d5bd1938fa1 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 15:15:23 +0800 Subject: [PATCH 47/56] osx: Fix setting size constraints for frameless window --- atom/browser/native_window_mac.mm | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index bb00a82451..5f867d9b1a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -22,11 +22,6 @@ namespace { -// Converts gfx::Size to NSSize. -inline NSSize ToNSSize(const gfx::Size& size) { - return NSMakeSize(size.width(), size.height()); -} - // Prevents window from resizing during the scope. class ScopedDisableResize { public: @@ -556,13 +551,25 @@ gfx::Rect NativeWindowMac::GetBounds() { void NativeWindowMac::SetContentSizeConstraints( const extensions::SizeConstraints& size_constraints) { + auto convertSize = [this](const gfx::Size& size) { + // 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 = ToNSSize(size_constraints.GetMinimumSize()); + NSSize min_size = convertSize(size_constraints.GetMinimumSize()); [window_ setContentMinSize:[content convertSize:min_size toView:nil]]; } if (size_constraints.HasMaximumSize()) { - NSSize max_size = ToNSSize(size_constraints.GetMaximumSize()); + NSSize max_size = convertSize(size_constraints.GetMaximumSize()); [window_ setContentMaxSize:[content convertSize:max_size toView:nil]]; } NativeWindow::SetContentSizeConstraints(size_constraints); From 898db4d6bd5838b2461174726d022054f19f123e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 15:23:23 +0800 Subject: [PATCH 48/56] osx: Set resizable flag when creating window Setting resizable for frameless window before it is shown will change its size. --- atom/browser/native_window.cc | 2 ++ atom/browser/native_window_mac.mm | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 981804cb22..dd4694b3bd 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -134,10 +134,12 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { } else { SetSizeConstraints(size_constraints); } +#if defined(OS_WIN) || defined(USE_X11) bool resizable; if (options.Get(switches::kResizable, &resizable)) { SetResizable(resizable); } +#endif bool top; if (options.Get(switches::kAlwaysOnTop, &top) && top) { SetAlwaysOnTop(true); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 5f867d9b1a..6420345da9 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -350,6 +350,8 @@ NativeWindowMac::NativeWindowMac( bool useStandardWindow = true; options.Get(switches::kStandardWindow, &useStandardWindow); + bool resizable = true; + options.Get(switches::kResizable, &resizable); // New title bar styles are available in Yosemite or newer std::string titleBarStyle; @@ -357,10 +359,13 @@ NativeWindowMac::NativeWindowMac( options.Get(switches::kTitleBarStyle, &titleBarStyle); NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSResizableWindowMask; + NSMiniaturizableWindowMask; if (!useStandardWindow || transparent() || !has_frame()) { styleMask |= NSTexturedBackgroundWindowMask; } + if (resizable) { + styleMask |= NSResizableWindowMask; + } if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) { styleMask |= NSFullSizeContentViewWindowMask; styleMask |= NSUnifiedTitleAndToolbarWindowMask; From 8e4094793890cc060912fffb30849e7f7322cdec Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 15:43:36 +0800 Subject: [PATCH 49/56] spec: Make window.open specs more reliable --- spec/chromium-spec.coffee | 41 ++++++++++++-------------- spec/fixtures/pages/window-opener.html | 5 +++- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index a782079026..2c4853a0d6 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -4,10 +4,17 @@ https = require 'https' path = require 'path' ws = require 'ws' remote = require 'remote' +BrowserWindow = remote.require 'browser-window' describe 'chromium feature', -> fixtures = path.resolve __dirname, 'fixtures' + listener = null + afterEach -> + if listener? + window.removeEventListener 'message', listener + listener = null + xdescribe 'heap snapshot', -> it 'does not crash', -> process.atomBinding('v8_util').takeHeapSnapshot() @@ -24,20 +31,17 @@ describe 'chromium feature', -> $.get "http://127.0.0.1:#{port}" describe 'document.hidden', -> - BrowserWindow = remote.require 'browser-window' - ipc = remote.require 'ipc' url = "file://#{fixtures}/pages/document-hidden.html" w = null afterEach -> w?.destroy() - ipc.removeAllListeners 'hidden' it 'is set correctly when window is not shown', (done) -> - ipc.once 'hidden', (event, hidden) -> - assert hidden - done() w = new BrowserWindow(show:false) + w.webContents.on 'ipc-message', (event, args) -> + assert.deepEqual args, ['hidden', true] + done() w.loadUrl url describe 'navigator.webkitGetUserMedia', -> @@ -52,8 +56,6 @@ describe 'chromium feature', -> assert.notEqual navigator.language, '' describe 'window.open', -> - @timeout 10000 - it 'returns a BrowserWindowProxy object', -> b = window.open 'about:blank', '', 'show=no' assert.equal b.closed, false @@ -62,46 +64,41 @@ describe 'chromium feature', -> it 'accepts "node-integration" as feature', (done) -> listener = (event) -> - window.removeEventListener 'message', listener - b.close() assert.equal event.data, 'undefined' + b.close() done() window.addEventListener 'message', listener b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no' it 'inherit options of parent window', (done) -> listener = (event) -> - window.removeEventListener 'message', listener - b.close() size = remote.getCurrentWindow().getSize() assert.equal event.data, "size: #{size.width} #{size.height}" + b.close() done() window.addEventListener 'message', listener b = window.open "file://#{fixtures}/pages/window-open-size.html", '', 'show=no' describe 'window.opener', -> - @timeout 10000 - - ipc = remote.require 'ipc' url = "file://#{fixtures}/pages/window-opener.html" w = null afterEach -> w?.destroy() - ipc.removeAllListeners 'opener' it 'is null for main window', (done) -> - ipc.once 'opener', (event, opener) -> - assert.equal opener, null - done() - BrowserWindow = remote.require 'browser-window' w = new BrowserWindow(show: false) + w.webContents.on 'ipc-message', (event, args) -> + assert.deepEqual args, ['opener', null] + done() w.loadUrl url it 'is not null for window opened by window.open', (done) -> - ipc.once 'opener', (event, opener) -> + listener = (event) -> + assert.equal event.data, 'object' b.close() - done(if opener isnt null then undefined else opener) + done() + window.addEventListener 'message', listener b = window.open url, '', 'show=no' describe 'window.opener.postMessage', -> diff --git a/spec/fixtures/pages/window-opener.html b/spec/fixtures/pages/window-opener.html index 0b5ecd556c..226b57dbd7 100644 --- a/spec/fixtures/pages/window-opener.html +++ b/spec/fixtures/pages/window-opener.html @@ -1,7 +1,10 @@ From f6327de7f748fe92de91aa6cc99db9df64c6fe09 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 16:08:32 +0800 Subject: [PATCH 50/56] spec: Increase timeout for window.open specs --- spec/chromium-spec.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/chromium-spec.coffee b/spec/chromium-spec.coffee index 2c4853a0d6..a034f93782 100644 --- a/spec/chromium-spec.coffee +++ b/spec/chromium-spec.coffee @@ -56,6 +56,8 @@ describe 'chromium feature', -> assert.notEqual navigator.language, '' describe 'window.open', -> + @timeout 10000 + it 'returns a BrowserWindowProxy object', -> b = window.open 'about:blank', '', 'show=no' assert.equal b.closed, false @@ -80,6 +82,8 @@ describe 'chromium feature', -> b = window.open "file://#{fixtures}/pages/window-open-size.html", '', 'show=no' describe 'window.opener', -> + @timeout 10000 + url = "file://#{fixtures}/pages/window-opener.html" w = null From e06778178a1f5369c93530d678e6af059f59995b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 16:06:39 +0800 Subject: [PATCH 51/56] linux: Restore size constraints when became sizable --- atom/browser/native_window_views.cc | 19 +++++++++++++++---- atom/browser/native_window_views.h | 7 +++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 0e04414b6a..6d89ee1d06 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -387,6 +387,15 @@ gfx::Size NativeWindowViews::GetContentSize() { return web_view_->size(); } +void NativeWindowViews::SetContentSizeConstraints( + const extensions::SizeConstraints& size_constraints) { + NativeWindow::SetContentSizeConstraints(size_constraints); +#if defined(USE_X11) + if (resizable_) + old_size_constraints_ = size_constraints; +#endif +} + void NativeWindowViews::SetResizable(bool resizable) { #if defined(OS_WIN) // WS_MAXIMIZEBOX => Maximize button @@ -403,11 +412,13 @@ void NativeWindowViews::SetResizable(bool resizable) { // On Linux there is no "resizable" property of a window, we have to set // both the minimum and maximum size to the window size to achieve it. if (resizable) { - SetMaximumSize(gfx::Size()); - SetMinimumSize(gfx::Size()); + SetContentSizeConstraints(old_size_constraints_); } else { - SetMaximumSize(GetSize()); - SetMinimumSize(GetSize()); + old_size_constraints_ = GetContentSizeConstraints(); + resizable_ = false; + gfx::Size content_size = GetContentSize(); + SetContentSizeConstraints( + extensions::SizeConstraints(content_size, content_size)); } } #endif diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 35ca7b63e2..0014acd073 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -64,6 +64,8 @@ class NativeWindowViews : public NativeWindow, void SetBounds(const gfx::Rect& bounds) override; gfx::Rect GetBounds() override; gfx::Size GetContentSize() override; + void SetContentSizeConstraints( + const extensions::SizeConstraints& size_constraints) override; void SetResizable(bool resizable) override; bool IsResizable() override; void SetAlwaysOnTop(bool top) override; @@ -165,6 +167,11 @@ class NativeWindowViews : public NativeWindow, // Handles window state events. scoped_ptr 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) // Weak ref. AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_; From f607e81facac1dd27665ef4a81469ff1ea4bdd82 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 16:16:02 +0800 Subject: [PATCH 52/56] views: Make size constraints work immediately after set --- atom/browser/native_window_views.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 6d89ee1d06..4c8d014b1e 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -390,6 +390,7 @@ gfx::Size NativeWindowViews::GetContentSize() { void NativeWindowViews::SetContentSizeConstraints( const extensions::SizeConstraints& size_constraints) { NativeWindow::SetContentSizeConstraints(size_constraints); + window_->OnSizeConstraintsChanged(); #if defined(USE_X11) if (resizable_) old_size_constraints_ = size_constraints; From c6d5a92d349bb376c4c6f78ed618b970d343258b Mon Sep 17 00:00:00 2001 From: Plusb Preco Date: Tue, 6 Oct 2015 19:53:35 +0900 Subject: [PATCH 53/56] Update as upstream --- README-ko.md | 2 +- docs-translations/ko-KR/api/native-image.md | 2 +- docs-translations/ko-KR/api/process.md | 6 ++++-- docs-translations/ko-KR/api/screen.md | 2 +- docs-translations/ko-KR/tutorial/quick-start.md | 6 +++--- .../ko-KR/tutorial/using-native-node-modules.md | 14 ++++++++------ 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/README-ko.md b/README-ko.md index 1481e7ce3d..c722243eb5 100644 --- a/README-ko.md +++ b/README-ko.md @@ -8,7 +8,7 @@ :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)에 사용되고 있습니다. Electron에 대한 중요한 알림을 받고 싶다면 Twitter에서 [@ElectronJS](https://twitter.com/electronjs)를 팔로우 하세요. diff --git a/docs-translations/ko-KR/api/native-image.md b/docs-translations/ko-KR/api/native-image.md index 423cedb983..485ab7bc71 100644 --- a/docs-translations/ko-KR/api/native-image.md +++ b/docs-translations/ko-KR/api/native-image.md @@ -142,4 +142,4 @@ var image = NativeImage.createFromPath('/Users/somebody/images/icon.png'); 이미지가 템플릿 이미지인지 확인합니다. -[buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer +[buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer diff --git a/docs-translations/ko-KR/api/process.md b/docs-translations/ko-KR/api/process.md index 57ba0fa768..a35c8b4e93 100644 --- a/docs-translations/ko-KR/api/process.md +++ b/docs-translations/ko-KR/api/process.md @@ -17,9 +17,11 @@ Electron 내부 초기화 스크립트의 로드가 완료되고, 웹 페이지 ```javascript // preload.js +var _setImmediate = setImmediate; +var _clearImmediate = clearImmediate; process.once('loaded', function() { - global.setImmediate = setImmediate; - global.clearImmediate = clearImmediate; + global.setImmediate = _setImmediate; + global.clearImmediate = _clearImmediate; }); ``` diff --git a/docs-translations/ko-KR/api/screen.md b/docs-translations/ko-KR/api/screen.md index de2d8baf4e..c65540eba2 100644 --- a/docs-translations/ko-KR/api/screen.md +++ b/docs-translations/ko-KR/api/screen.md @@ -45,7 +45,7 @@ app.on('ready', function() { if (externalDisplay) { mainWindow = new BrowserWindow({ x: externalDisplay.bounds.x + 50, - y: externalDisplay.bounds.y + 50, + y: externalDisplay.bounds.y + 50 }); } }); diff --git a/docs-translations/ko-KR/tutorial/quick-start.md b/docs-translations/ko-KR/tutorial/quick-start.md index 3edf13cc47..6eaad74769 100644 --- a/docs-translations/ko-KR/tutorial/quick-start.md +++ b/docs-translations/ko-KR/tutorial/quick-start.md @@ -3,7 +3,7 @@ ## 소개 Electron은 자바스크립트와 함께 제공된 풍부한 네이티브 API를 사용하여 멋진 데스크탑 어플리케이션을 만들 수 있도록 해주는 프레임워크입니다. -이 프레임워크의 io.js(node.js)는 웹 서버 개발이 아닌 데스크탑 어플리케이션 개발에 초점을 맞췄습니다. +이 프레임워크의 Node.js는 웹 서버 개발이 아닌 데스크탑 어플리케이션 개발에 초점을 맞췄습니다. 이 말은 Electron이 GUI 라이브러리의 자바스크립트 바인딩이라는 뜻이 아닙니다. 대신, Electron은 웹 페이지의 GUI를 사용합니다. 쉽게 말해 Electron은 자바스크립트를 사용하여 조작하는 작은 Chromium 브라우저로 볼 수 있습니다. @@ -19,7 +19,7 @@ Electron이 웹페이지를 보여줄 때 Chromium의 multi-processes 구조도 Electron 프로세스 내에서 작동하는 웹 페이지를 __랜더러 프로세스__ 라고 불립니다. 보통 일반 브라우저의 웹 페이지들은 샌드박스가 적용된 환경에서 작동하며 네이티브 리소스에는 접근할 수 없도록 되어 있습니다. -하지만 Electron은 웹 페이지 내에서 io.js(node.js) API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 있습니다. +하지만 Electron은 웹 페이지 내에서 Node.js API를 사용하여 low-level 수준으로 운영체제와 상호작용할 수 있습니다. ### 메인 프로세스와 랜더러 프로세스의 차이점 @@ -116,7 +116,7 @@ app.on('ready', function() {

헬로 월드!

- 이 어플리케이션은 io.js 과 + 이 어플리케이션은 Node.js 과 Electron 을 사용합니다. diff --git a/docs-translations/ko-KR/tutorial/using-native-node-modules.md b/docs-translations/ko-KR/tutorial/using-native-node-modules.md index ed64abb492..6a0c67770b 100644 --- a/docs-translations/ko-KR/tutorial/using-native-node-modules.md +++ b/docs-translations/ko-KR/tutorial/using-native-node-modules.md @@ -5,14 +5,16 @@ Electron에선 node.js 네이티브 모듈이 지원됩니다. 하지만 Electro ## 네이티브 node 모듈 호환성 -Node v0.11.x 버전부터는 V8 API의 중대한 변경이 있었습니다. 하지만 대부분의 네이티브 모듈은 Node v0.10.x 버전을 타겟으로 작성 되었기 때문에 -새로운 Node 또는 io.js 버전에서 작동하지 않을 수 있습니다. Electron은 내부적으로 __io.js v3.1.0__ 버전을 사용하기 때문에 호환성 문제가 발생할 수 있습니다. +네이티브 모듈은 node.js가 새로운 V8 버전을 사용함으로 인해 작동하지 않을 수 있습니다. +사용하는 네이티브 모듈이 Electron에 맞춰 작동할 수 있도록 하려면 Electron에서 사용하는 node.js의 버전을 확인할 필요가 있습니다. +Electron에서 사용하는 node 버전은 [releases](https://github.com/atom/electron/releases)에서 확인할 수 있으며 +`process.version`을 출력하여 버전을 확인할 수도 있습니다. ([시작하기](https://github.com/atom/electron/blob/master/docs/tutorial/quick-start.md)의 예제를 참고하세요) -이 문제를 해결하기 위해선 모듈이 v0.11.x 또는 최신 버전을 지원할 수 있도록 변경해야 합니다. -현재 [많은 모듈들](https://www.npmjs.org/browse/depended/nan)이 안정적으로 두 버전 모두 지원하고 있지만 오래된 모듈의 경우 여전히 Node v0.10.x 버전만을 지원하고 있습니다. -예를 들어 [nan](https://github.com/rvagg/nan) 모듈을 사용해야 한다면 Node v0.11.x 또는 최신 버전의 Node와 io.js로 포팅 할 필요가 있습니다. +혹시 직접 만든 네이티브 모듈이 있다면 [NAN](https://github.com/nodejs/nan/) 모듈을 사용하는 것을 고려해보는 것이 좋습니다. +이 모듈은 다중 버전의 node.js를 지원하기 쉽게 해줍니다. 이를 통해 오래된 모듈을 새 버전의 node.js에 맞게 포팅할 수 있습니다. +Electron도 이 모듈을 통해 포팅된 네이티브 모듈을 사용할 수 있습니다. -## 네이티브 모듈 설치하는 방법 +## 네이티브 모듈을 설치하는 방법 네이티브 모듈을 설치하는 방법은 세 가지 종류가 있습니다. From c916baa93968c6d874a94696a0f44868bbc18f11 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 21:40:08 +0800 Subject: [PATCH 54/56] Update brightray, fix #2315 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index c44f99278b..9e97c2b5bf 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit c44f99278bc4f6823f81b6f3a8d75881d697fd01 +Subproject commit 9e97c2b5bf5aa455f863bb29f99a219bdda4d29d From 927c3f34c3759e29948a1ffaa76a4985d38a1d69 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 22:25:55 +0800 Subject: [PATCH 55/56] Guard against undefined, fix #2995 In theory this should never happen, seems like some object is garbage collected after the JavaScript context has been destroyed. --- atom/browser/lib/objects-registry.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/atom/browser/lib/objects-registry.coffee b/atom/browser/lib/objects-registry.coffee index ccfe2dbe0a..667adbc24e 100644 --- a/atom/browser/lib/objects-registry.coffee +++ b/atom/browser/lib/objects-registry.coffee @@ -34,6 +34,7 @@ class ObjectsRegistry extends EventEmitter @dereference id, 1 # Also reduce the count in owner. pointer = @owners[webContentsId] + return unless pointer? --pointer[id] delete pointer[id] if pointer[id] is 0 @@ -57,6 +58,7 @@ class ObjectsRegistry extends EventEmitter # Private: Dereference the object from store. dereference: (id, count) -> pointer = @storage[id] + return unless pointer? pointer.count -= count if pointer.count is 0 v8Util.deleteHiddenValue pointer.object, 'atomId' From 5bdc077b486885e5769230b40c4ae7f54b29aea9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 6 Oct 2015 22:45:00 +0800 Subject: [PATCH 56/56] Update brightray for #2855 --- vendor/brightray | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/brightray b/vendor/brightray index 9e97c2b5bf..c25b9b2784 160000 --- a/vendor/brightray +++ b/vendor/brightray @@ -1 +1 @@ -Subproject commit 9e97c2b5bf5aa455f863bb29f99a219bdda4d29d +Subproject commit c25b9b27845a308e6a6a5966dad057d721b1f3d1