commit
cb22b88e6a
34 changed files with 639 additions and 384 deletions
|
@ -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)를 팔로우 하세요.
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -112,27 +112,34 @@ 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();
|
||||
}
|
||||
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);
|
||||
}
|
||||
#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);
|
||||
|
@ -178,6 +185,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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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) = 0;
|
||||
virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size) = 0;
|
||||
|
||||
// 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<SkRegion> draggable_region_; // used in custom drag.
|
||||
|
||||
// Minimum and maximum size, stored as content size.
|
||||
extensions::SizeConstraints size_constraints_;
|
||||
|
||||
// Whether window can be resized larger than screen.
|
||||
bool enable_larger_than_screen_;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -549,56 +554,30 @@ 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) {
|
||||
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 = convertSize(size_constraints.GetMinimumSize());
|
||||
[window_ setContentMinSize:[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 = convertSize(size_constraints.GetMaximumSize());
|
||||
[window_ setContentMaxSize:[content convertSize:max_size toView:nil]];
|
||||
}
|
||||
NativeWindow::SetContentSizeConstraints(size_constraints);
|
||||
}
|
||||
|
||||
void NativeWindowMac::SetResizable(bool resizable) {
|
||||
|
@ -821,6 +800,24 @@ 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);
|
||||
}
|
||||
|
||||
void NativeWindowMac::InstallView() {
|
||||
// Make sure the bottom corner is rounded: http://crbug.com/396264.
|
||||
[[window_ contentView] setWantsLayer:YES];
|
||||
|
|
|
@ -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,
|
||||
|
@ -186,7 +122,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 +208,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 +248,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,42 +378,23 @@ gfx::Rect NativeWindowViews::GetBounds() {
|
|||
return window_->GetWindowBoundsInScreen();
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
|
||||
if (!has_frame()) {
|
||||
NativeWindow::SetSize(size);
|
||||
return;
|
||||
}
|
||||
|
||||
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
|
||||
bounds.set_size(size);
|
||||
SetBounds(ContentBoundsToWindowBounds(bounds));
|
||||
}
|
||||
|
||||
gfx::Size NativeWindowViews::GetContentSize() {
|
||||
if (!has_frame())
|
||||
return GetSize();
|
||||
#if defined(OS_WIN)
|
||||
if (IsMinimized())
|
||||
return NativeWindow::GetContentSize();
|
||||
#endif
|
||||
|
||||
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;
|
||||
return web_view_->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::SetContentSizeConstraints(
|
||||
const extensions::SizeConstraints& size_constraints) {
|
||||
NativeWindow::SetContentSizeConstraints(size_constraints);
|
||||
window_->OnSizeConstraintsChanged();
|
||||
#if defined(USE_X11)
|
||||
if (resizable_)
|
||||
old_size_constraints_ = size_constraints;
|
||||
#endif
|
||||
}
|
||||
|
||||
void NativeWindowViews::SetResizable(bool resizable) {
|
||||
|
@ -494,11 +413,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
|
||||
|
@ -610,8 +531,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,103 +751,45 @@ 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::WindowSizeToFramelessSize(
|
||||
const gfx::Size& size) {
|
||||
if (size.width() == 0 && size.height() == 0)
|
||||
gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) {
|
||||
if (!has_frame())
|
||||
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()) {
|
||||
gfx::Size window_size(size);
|
||||
#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();
|
||||
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
|
||||
window_bounds.set_height(window_bounds.height() - frame_size.height());
|
||||
window_bounds.set_width(window_bounds.width() - frame_size.width());
|
||||
}
|
||||
|
||||
return window_bounds.size();
|
||||
if (menu_bar_ && menu_bar_visible_)
|
||||
window_size.set_height(window_size.height() + kMenuBarHeight);
|
||||
return window_size;
|
||||
}
|
||||
|
||||
gfx::Size NativeWindowViews::WindowSizeToContentSize(const gfx::Size& size) {
|
||||
if (!has_frame())
|
||||
return size;
|
||||
|
||||
gfx::Size content_size(size);
|
||||
#if defined(OS_WIN)
|
||||
content_size = gfx::win::DIPToScreenSize(content_size);
|
||||
RECT rect;
|
||||
SetRectEmpty(&rect);
|
||||
HWND hwnd = GetAcceleratedWidget();
|
||||
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
|
||||
DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
AdjustWindowRectEx(&rect, style, FALSE, ex_style);
|
||||
content_size.set_width(content_size.width() - (rect.right - rect.left));
|
||||
content_size.set_height(content_size.height() - (rect.bottom - rect.top));
|
||||
content_size = gfx::win::ScreenToDIPSize(content_size);
|
||||
#endif
|
||||
|
||||
if (menu_bar_ && menu_bar_visible_)
|
||||
content_size.set_height(content_size.height() - kMenuBarHeight);
|
||||
return content_size;
|
||||
}
|
||||
|
||||
void NativeWindowViews::HandleKeyboardEvent(
|
||||
|
@ -954,6 +833,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);
|
||||
|
@ -976,26 +863,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;
|
||||
|
|
|
@ -63,12 +63,9 @@ class NativeWindowViews : 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;
|
||||
|
@ -94,8 +91,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)
|
||||
|
@ -142,20 +137,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();
|
||||
|
||||
|
@ -172,6 +167,11 @@ class NativeWindowViews : public NativeWindow,
|
|||
|
||||
// Handles window state events.
|
||||
scoped_ptr<WindowStateWatcher> window_state_watcher_;
|
||||
|
||||
// The "resizable" flag on Linux is implemented by setting size constraints,
|
||||
// we need to make sure size constraints are restored when window becomes
|
||||
// resizable again.
|
||||
extensions::SizeConstraints old_size_constraints_;
|
||||
#elif defined(OS_WIN)
|
||||
// Weak ref.
|
||||
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
|
||||
|
@ -197,8 +197,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);
|
||||
|
|
145
atom/browser/native_window_views_win.cc
Normal file
145
atom/browser/native_window_views_win.cc
Normal file
|
@ -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.
|
||||
NativeWindow::SetSize(last_normal_size_);
|
||||
|
||||
NotifyWindowUnmaximize();
|
||||
break;
|
||||
case ui::SHOW_STATE_MINIMIZED:
|
||||
if (IsFullscreen()) {
|
||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||
NotifyWindowEnterFullScreen();
|
||||
} else {
|
||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||
|
||||
// When the window is restored we resize it to the previous known
|
||||
// normal size.
|
||||
NativeWindow::SetSize(last_normal_size_);
|
||||
|
||||
NotifyWindowRestore();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace atom
|
|
@ -104,11 +104,11 @@ gfx::Size FramelessView::GetPreferredSize() const {
|
|||
}
|
||||
|
||||
gfx::Size FramelessView::GetMinimumSize() const {
|
||||
return window_->GetMinimumSize();
|
||||
return window_->GetContentSizeConstraints().GetMinimumSize();
|
||||
}
|
||||
|
||||
gfx::Size FramelessView::GetMaximumSize() const {
|
||||
return window_->GetMaximumSize();
|
||||
return window_->GetContentSizeConstraints().GetMaximumSize();
|
||||
}
|
||||
|
||||
const char* FramelessView::GetClassName() const {
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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(
|
||||
window_->GetMinimumSize());
|
||||
return gfx::win::DIPToScreenSize(size);
|
||||
}
|
||||
|
||||
gfx::Size WinFrameView::GetMaximumSize() const {
|
||||
gfx::Size size = window_->WindowSizeToFramelessSize(
|
||||
window_->GetMaximumSize());
|
||||
return gfx::win::DIPToScreenSize(size);
|
||||
}
|
||||
|
||||
const char* WinFrameView::GetClassName() const {
|
||||
return kViewClassName;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ struct Converter<blink::WebInputEvent::Type> {
|
|||
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")
|
||||
|
|
|
@ -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 <algorithm>
|
||||
|
||||
#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
|
|
@ -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_
|
|
@ -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
|
||||
|
|
|
@ -7,6 +7,24 @@ Electron의 `process` 객체는 기존의 node와는 달리 약간의 차이점
|
|||
* `process.versions['chrome']` String - Chromium의 버전.
|
||||
* `process.resourcesPath` String - JavaScript 소스코드의 경로.
|
||||
|
||||
## Events
|
||||
|
||||
### Event: 'loaded'
|
||||
|
||||
Electron 내부 초기화 스크립트의 로드가 완료되고, 웹 페이지나 메인 스크립트를 로드하기 시작할 때 발생하는 이벤트입니다.
|
||||
|
||||
이 이벤트는 preload 스크립트를 통해 node 통합이 꺼져있는 전역 스코프에 node의 전역 심볼들을 다시 추가할 때 사용할 수 있습니다:
|
||||
|
||||
```javascript
|
||||
// preload.js
|
||||
var _setImmediate = setImmediate;
|
||||
var _clearImmediate = clearImmediate;
|
||||
process.once('loaded', function() {
|
||||
global.setImmediate = _setImmediate;
|
||||
global.clearImmediate = _clearImmediate;
|
||||
});
|
||||
```
|
||||
|
||||
## Methods
|
||||
|
||||
`process` 객체는 다음과 같은 메서드를 가지고 있습니다:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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() {
|
|||
</head>
|
||||
<body>
|
||||
<h1>헬로 월드!</h1>
|
||||
이 어플리케이션은 io.js <script>document.write(process.version)</script> 과
|
||||
이 어플리케이션은 Node.js <script>document.write(process.version)</script> 과
|
||||
Electron <script>document.write(process.versions['electron'])</script>을 사용합니다.
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -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도 이 모듈을 통해 포팅된 네이티브 모듈을 사용할 수 있습니다.
|
||||
|
||||
## 네이티브 모듈 설치하는 방법
|
||||
## 네이티브 모듈을 설치하는 방법
|
||||
|
||||
네이티브 모듈을 설치하는 방법은 세 가지 종류가 있습니다.
|
||||
|
||||
|
|
|
@ -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)`
|
||||
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
```
|
||||
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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:
|
|||
</head>
|
||||
<body>
|
||||
<h1>Hello World!</h1>
|
||||
We are using io.js <script>document.write(process.version)</script>
|
||||
We are using Node.js <script>document.write(process.version)</script>
|
||||
and Electron <script>document.write(process.versions['electron'])</script>.
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,19 +4,27 @@ Following platforms are supported by Electron:
|
|||
|
||||
### OS X
|
||||
|
||||
Only 64bit binaries are provided for OS X, and the minimum OS X version supported is OS X 10.8.
|
||||
Only 64bit binaries are provided for OS X, and the minimum OS X version
|
||||
supported is OS X 10.8.
|
||||
|
||||
### 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. Please note, the `ARM` version of Windows is not supported for now.
|
||||
Both `x86` and `amd64` (x64) binaries are provided for Windows. Please note, the
|
||||
`ARM` version of Windows is not supported for now.
|
||||
|
||||
### Linux
|
||||
|
||||
The prebuilt `ia32`(`i686`) and `x64`(`amd64`) binaries of Electron are built on Ubuntu 12.04, the `arm` binary is built against ARM v7 with hard-float ABI and NEON for Debian Wheezy.
|
||||
The prebuilt `ia32`(`i686`) and `x64`(`amd64`) binaries of Electron are built on
|
||||
Ubuntu 12.04, the `arm` binary is built against ARM v7 with hard-float ABI and
|
||||
NEON for Debian Wheezy.
|
||||
|
||||
Whether the prebuilt binary can run on a distribution depends on whether the distribution includes the libraries that Electron is linked to on the building platform, so only Ubuntu 12.04 is guaranteed to work, but following platforms are also verified to be able to run the prebuilt binaries of Electron:
|
||||
Whether the prebuilt binary can run on a distribution depends on whether the
|
||||
distribution includes the libraries that Electron is linked to on the building
|
||||
platform, so only Ubuntu 12.04 is guaranteed to work, but following platforms
|
||||
are also verified to be able to run the prebuilt binaries of Electron:
|
||||
|
||||
* Ubuntu 12.04 and later
|
||||
* Fedora 21
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
@ -429,6 +430,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',
|
||||
|
|
|
@ -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', ->
|
||||
|
@ -62,19 +66,17 @@ 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'
|
||||
|
@ -82,26 +84,25 @@ describe 'chromium feature', ->
|
|||
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', ->
|
||||
|
|
5
spec/fixtures/pages/window-opener.html
vendored
5
spec/fixtures/pages/window-opener.html
vendored
|
@ -1,7 +1,10 @@
|
|||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
require('ipc').send('opener', window.opener);
|
||||
if (window.opener !== null)
|
||||
window.opener.postMessage(typeof window.opener, '*');
|
||||
else
|
||||
require('ipc').send('opener', window.opener);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
2
vendor/brightray
vendored
2
vendor/brightray
vendored
|
@ -1 +1 @@
|
|||
Subproject commit c44f99278bc4f6823f81b6f3a8d75881d697fd01
|
||||
Subproject commit c25b9b27845a308e6a6a5966dad057d721b1f3d1
|
Loading…
Reference in a new issue