Merge remote-tracking branch 'atom/master'

This commit is contained in:
Plusb Preco 2015-10-10 15:10:24 +09:00
commit ccd17f060d
28 changed files with 606 additions and 371 deletions

View file

@ -7,7 +7,7 @@
:zap: *Formerly known as Atom Shell* :zap: :zap: *Formerly known as Atom Shell* :zap:
The Electron framework lets you write cross-platform desktop applications The Electron framework lets you write cross-platform desktop applications
using JavaScript, HTML and CSS. It is based on [io.js](http://iojs.org) and using JavaScript, HTML and CSS. It is based on [Node.js](https://nodejs.org) and
[Chromium](http://www.chromium.org) and is used in the [Atom [Chromium](http://www.chromium.org) and is used in the [Atom
editor](https://github.com/atom/atom). editor](https://github.com/atom/atom).

View file

@ -34,6 +34,7 @@ class ObjectsRegistry extends EventEmitter
@dereference id, 1 @dereference id, 1
# Also reduce the count in owner. # Also reduce the count in owner.
pointer = @owners[webContentsId] pointer = @owners[webContentsId]
return unless pointer?
--pointer[id] --pointer[id]
delete pointer[id] if pointer[id] is 0 delete pointer[id] if pointer[id] is 0
@ -57,6 +58,7 @@ class ObjectsRegistry extends EventEmitter
# Private: Dereference the object from store. # Private: Dereference the object from store.
dereference: (id, count) -> dereference: (id, count) ->
pointer = @storage[id] pointer = @storage[id]
return unless pointer?
pointer.count -= count pointer.count -= count
if pointer.count is 0 if pointer.count is 0
v8Util.deleteHiddenValue pointer.object, 'atomId' v8Util.deleteHiddenValue pointer.object, 'atomId'

View file

@ -112,27 +112,34 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
int x = -1, y = -1; int x = -1, y = -1;
bool center; bool center;
if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) { if (options.Get(switches::kX, &x) && options.Get(switches::kY, &y)) {
int width = -1, height = -1; SetPosition(gfx::Point(x, y));
options.Get(switches::kWidth, &width);
options.Get(switches::kHeight, &height);
SetBounds(gfx::Rect(x, y, width, height));
} else if (options.Get(switches::kCenter, &center) && center) { } else if (options.Get(switches::kCenter, &center) && center) {
Center(); Center();
} }
extensions::SizeConstraints size_constraints;
int min_height = 0, min_width = 0; int min_height = 0, min_width = 0;
if (options.Get(switches::kMinHeight, &min_height) | if (options.Get(switches::kMinHeight, &min_height) |
options.Get(switches::kMinWidth, &min_width)) { options.Get(switches::kMinWidth, &min_width)) {
SetMinimumSize(gfx::Size(min_width, min_height)); size_constraints.set_minimum_size(gfx::Size(min_width, min_height));
} }
int max_height = INT_MAX, max_width = INT_MAX; int max_height = INT_MAX, max_width = INT_MAX;
if (options.Get(switches::kMaxHeight, &max_height) | if (options.Get(switches::kMaxHeight, &max_height) |
options.Get(switches::kMaxWidth, &max_width)) { options.Get(switches::kMaxWidth, &max_width)) {
SetMaximumSize(gfx::Size(max_width, max_height)); size_constraints.set_maximum_size(gfx::Size(max_width, max_height));
} }
bool use_content_size = false;
options.Get(switches::kUseContentSize, &use_content_size);
if (use_content_size) {
SetContentSizeConstraints(size_constraints);
} else {
SetSizeConstraints(size_constraints);
}
#if defined(OS_WIN) || defined(USE_X11)
bool resizable; bool resizable;
if (options.Get(switches::kResizable, &resizable)) { if (options.Get(switches::kResizable, &resizable)) {
SetResizable(resizable); SetResizable(resizable);
} }
#endif
bool top; bool top;
if (options.Get(switches::kAlwaysOnTop, &top) && top) { if (options.Get(switches::kAlwaysOnTop, &top) && top) {
SetAlwaysOnTop(true); SetAlwaysOnTop(true);
@ -178,6 +185,67 @@ gfx::Point NativeWindow::GetPosition() {
return GetBounds().origin(); return GetBounds().origin();
} }
void NativeWindow::SetContentSize(const gfx::Size& size) {
SetSize(ContentSizeToWindowSize(size));
}
gfx::Size NativeWindow::GetContentSize() {
return WindowSizeToContentSize(GetSize());
}
void NativeWindow::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) {
extensions::SizeConstraints content_constraints;
if (window_constraints.HasMaximumSize())
content_constraints.set_maximum_size(
WindowSizeToContentSize(window_constraints.GetMaximumSize()));
if (window_constraints.HasMinimumSize())
content_constraints.set_minimum_size(
WindowSizeToContentSize(window_constraints.GetMinimumSize()));
SetContentSizeConstraints(content_constraints);
}
extensions::SizeConstraints NativeWindow::GetSizeConstraints() {
extensions::SizeConstraints content_constraints = GetContentSizeConstraints();
extensions::SizeConstraints window_constraints;
if (content_constraints.HasMaximumSize())
window_constraints.set_maximum_size(
ContentSizeToWindowSize(content_constraints.GetMaximumSize()));
if (content_constraints.HasMinimumSize())
window_constraints.set_minimum_size(
ContentSizeToWindowSize(content_constraints.GetMinimumSize()));
return window_constraints;
}
void NativeWindow::SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) {
size_constraints_ = size_constraints;
}
extensions::SizeConstraints NativeWindow::GetContentSizeConstraints() {
return size_constraints_;
}
void NativeWindow::SetMinimumSize(const gfx::Size& size) {
extensions::SizeConstraints size_constraints;
size_constraints.set_minimum_size(size);
SetSizeConstraints(size_constraints);
}
gfx::Size NativeWindow::GetMinimumSize() {
return GetSizeConstraints().GetMinimumSize();
}
void NativeWindow::SetMaximumSize(const gfx::Size& size) {
extensions::SizeConstraints size_constraints;
size_constraints.set_maximum_size(size);
SetSizeConstraints(size_constraints);
}
gfx::Size NativeWindow::GetMaximumSize() {
return GetSizeConstraints().GetMaximumSize();
}
void NativeWindow::SetRepresentedFilename(const std::string& filename) { void NativeWindow::SetRepresentedFilename(const std::string& filename) {
} }

View file

@ -19,6 +19,7 @@
#include "content/public/browser/readback_types.h" #include "content/public/browser/readback_types.h"
#include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h" #include "content/public/browser/web_contents_user_data.h"
#include "extensions/browser/app_window/size_constraints.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
@ -110,12 +111,18 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::Size GetSize(); virtual gfx::Size GetSize();
virtual void SetPosition(const gfx::Point& position); virtual void SetPosition(const gfx::Point& position);
virtual gfx::Point GetPosition(); virtual gfx::Point GetPosition();
virtual void SetContentSize(const gfx::Size& size) = 0; virtual void SetContentSize(const gfx::Size& size);
virtual gfx::Size GetContentSize() = 0; virtual gfx::Size GetContentSize();
virtual void SetMinimumSize(const gfx::Size& size) = 0; virtual void SetSizeConstraints(
virtual gfx::Size GetMinimumSize() = 0; const extensions::SizeConstraints& size_constraints);
virtual void SetMaximumSize(const gfx::Size& size) = 0; virtual extensions::SizeConstraints GetSizeConstraints();
virtual gfx::Size GetMaximumSize() = 0; virtual void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints);
virtual extensions::SizeConstraints GetContentSizeConstraints();
virtual void SetMinimumSize(const gfx::Size& size);
virtual gfx::Size GetMinimumSize();
virtual void SetMaximumSize(const gfx::Size& size);
virtual gfx::Size GetMaximumSize();
virtual void SetResizable(bool resizable) = 0; virtual void SetResizable(bool resizable) = 0;
virtual bool IsResizable() = 0; virtual bool IsResizable() = 0;
virtual void SetAlwaysOnTop(bool top) = 0; virtual void SetAlwaysOnTop(bool top) = 0;
@ -234,6 +241,10 @@ class NativeWindow : public base::SupportsUserData,
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents, NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options); const mate::Dictionary& options);
// 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: // content::WebContentsObserver:
void RenderViewCreated(content::RenderViewHost* render_view_host) override; void RenderViewCreated(content::RenderViewHost* render_view_host) override;
void BeforeUnloadDialogCancelled() override; void BeforeUnloadDialogCancelled() override;
@ -269,6 +280,9 @@ class NativeWindow : public base::SupportsUserData,
// has to been explicitly provided. // has to been explicitly provided.
scoped_ptr<SkRegion> draggable_region_; // used in custom drag. scoped_ptr<SkRegion> draggable_region_; // used in custom drag.
// Minimum and maximum size, stored as content size.
extensions::SizeConstraints size_constraints_;
// Whether window can be resized larger than screen. // Whether window can be resized larger than screen.
bool enable_larger_than_screen_; bool enable_larger_than_screen_;

View file

@ -44,12 +44,8 @@ class NativeWindowMac : public NativeWindow {
bool IsFullscreen() const override; bool IsFullscreen() const override;
void SetBounds(const gfx::Rect& bounds) override; void SetBounds(const gfx::Rect& bounds) override;
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
void SetContentSize(const gfx::Size& size) override; void SetContentSizeConstraints(
gfx::Size GetContentSize() override; const extensions::SizeConstraints& size_constraints) override;
void SetMinimumSize(const gfx::Size& size) override;
gfx::Size GetMinimumSize() override;
void SetMaximumSize(const gfx::Size& size) override;
gfx::Size GetMaximumSize() override;
void SetResizable(bool resizable) override; void SetResizable(bool resizable) override;
bool IsResizable() override; bool IsResizable() override;
void SetAlwaysOnTop(bool top) override; void SetAlwaysOnTop(bool top) override;
@ -89,6 +85,10 @@ class NativeWindowMac : public NativeWindow {
const content::NativeWebKeyboardEvent&) override; const content::NativeWebKeyboardEvent&) override;
private: private:
// NativeWindow:
gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override;
gfx::Size WindowSizeToContentSize(const gfx::Size& size) override;
void InstallView(); void InstallView();
void UninstallView(); void UninstallView();

View file

@ -350,6 +350,8 @@ NativeWindowMac::NativeWindowMac(
bool useStandardWindow = true; bool useStandardWindow = true;
options.Get(switches::kStandardWindow, &useStandardWindow); options.Get(switches::kStandardWindow, &useStandardWindow);
bool resizable = true;
options.Get(switches::kResizable, &resizable);
// New title bar styles are available in Yosemite or newer // New title bar styles are available in Yosemite or newer
std::string titleBarStyle; std::string titleBarStyle;
@ -357,10 +359,13 @@ NativeWindowMac::NativeWindowMac(
options.Get(switches::kTitleBarStyle, &titleBarStyle); options.Get(switches::kTitleBarStyle, &titleBarStyle);
NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask; NSMiniaturizableWindowMask;
if (!useStandardWindow || transparent() || !has_frame()) { if (!useStandardWindow || transparent() || !has_frame()) {
styleMask |= NSTexturedBackgroundWindowMask; styleMask |= NSTexturedBackgroundWindowMask;
} }
if (resizable) {
styleMask |= NSResizableWindowMask;
}
if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) { if ((titleBarStyle == "hidden") || (titleBarStyle == "hidden-inset")) {
styleMask |= NSFullSizeContentViewWindowMask; styleMask |= NSFullSizeContentViewWindowMask;
styleMask |= NSUnifiedTitleAndToolbarWindowMask; styleMask |= NSUnifiedTitleAndToolbarWindowMask;
@ -549,56 +554,30 @@ gfx::Rect NativeWindowMac::GetBounds() {
return bounds; return bounds;
} }
void NativeWindowMac::SetContentSize(const gfx::Size& size) { void NativeWindowMac::SetContentSizeConstraints(
if (!has_frame()) { const extensions::SizeConstraints& size_constraints) {
SetSize(size); auto convertSize = [this](const gfx::Size& size) {
return; // Our frameless window still has titlebar attached, so setting contentSize
// will result in actual content size being larger.
if (!has_frame()) {
NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
NSRect content = [window_ contentRectForFrameRect:frame];
return content.size;
} else {
return NSMakeSize(size.width(), size.height());
}
};
NSView* content = [window_ contentView];
if (size_constraints.HasMinimumSize()) {
NSSize min_size = convertSize(size_constraints.GetMinimumSize());
[window_ setContentMinSize:[content convertSize:min_size toView:nil]];
} }
if (size_constraints.HasMaximumSize()) {
NSRect frame_nsrect = [window_ frame]; NSSize max_size = convertSize(size_constraints.GetMaximumSize());
NSSize frame = frame_nsrect.size; [window_ setContentMaxSize:[content convertSize:max_size toView:nil]];
NSSize content = [window_ contentRectForFrameRect:frame_nsrect].size; }
NativeWindow::SetContentSizeConstraints(size_constraints);
int width = size.width() + frame.width - content.width;
int height = size.height() + frame.height - content.height;
frame_nsrect.origin.y -= height - frame_nsrect.size.height;
frame_nsrect.size.width = width;
frame_nsrect.size.height = height;
[window_ setFrame:frame_nsrect display:YES];
}
gfx::Size NativeWindowMac::GetContentSize() {
if (!has_frame())
return GetSize();
NSRect bounds = [[window_ contentView] bounds];
return gfx::Size(bounds.size.width, bounds.size.height);
}
void NativeWindowMac::SetMinimumSize(const gfx::Size& size) {
NSSize min_size = NSMakeSize(size.width(), size.height());
NSView* content = [window_ contentView];
[window_ setContentMinSize:[content convertSize:min_size toView:nil]];
}
gfx::Size NativeWindowMac::GetMinimumSize() {
NSView* content = [window_ contentView];
NSSize min_size = [content convertSize:[window_ contentMinSize]
fromView:nil];
return gfx::Size(min_size.width, min_size.height);
}
void NativeWindowMac::SetMaximumSize(const gfx::Size& size) {
NSSize max_size = NSMakeSize(size.width(), size.height());
NSView* content = [window_ contentView];
[window_ setContentMaxSize:[content convertSize:max_size toView:nil]];
}
gfx::Size NativeWindowMac::GetMaximumSize() {
NSView* content = [window_ contentView];
NSSize max_size = [content convertSize:[window_ contentMaxSize]
fromView:nil];
return gfx::Size(max_size.width, max_size.height);
} }
void NativeWindowMac::SetResizable(bool resizable) { void NativeWindowMac::SetResizable(bool resizable) {
@ -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() { void NativeWindowMac::InstallView() {
// Make sure the bottom corner is rounded: http://crbug.com/396264. // Make sure the bottom corner is rounded: http://crbug.com/396264.
[[window_ contentView] setWantsLayer:YES]; [[window_ contentView] setWantsLayer:YES];

View file

@ -77,70 +77,6 @@ bool IsAltModifier(const content::NativeWebKeyboardEvent& event) {
(modifiers == (Modifiers::AltKey | Modifiers::IsRight)); (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 { class NativeWindowClientView : public views::ClientView {
public: public:
NativeWindowClientView(views::Widget* widget, NativeWindowClientView(views::Widget* widget,
@ -186,7 +122,8 @@ NativeWindowViews::NativeWindowViews(
// will not allow us to resize the window larger than scree. // will not allow us to resize the window larger than scree.
// Setting directly to INT_MAX somehow doesn't work, so we just devide // Setting directly to INT_MAX somehow doesn't work, so we just devide
// by 10, which should still be large enough. // by 10, which should still be large enough.
maximum_size_.SetSize(INT_MAX / 10, INT_MAX / 10); SetContentSizeConstraints(extensions::SizeConstraints(
gfx::Size(), gfx::Size(INT_MAX / 10, INT_MAX / 10)));
int width = 800, height = 600; int width = 800, height = 600;
options.Get(switches::kWidth, &width); options.Get(switches::kWidth, &width);
@ -271,11 +208,6 @@ NativeWindowViews::NativeWindowViews(
set_background(views::Background::CreateStandardPanelBackground()); set_background(views::Background::CreateStandardPanelBackground());
AddChildView(web_view_); AddChildView(web_view_);
if (has_frame() &&
options.Get(switches::kUseContentSize, &use_content_size_) &&
use_content_size_)
bounds = ContentBoundsToWindowBounds(bounds);
#if defined(OS_WIN) #if defined(OS_WIN)
// Save initial window state. // Save initial window state.
if (fullscreen) if (fullscreen)
@ -316,8 +248,14 @@ NativeWindowViews::NativeWindowViews(
if (transparent() && !has_frame()) if (transparent() && !has_frame())
wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE); wm::SetShadowType(GetNativeWindow(), wm::SHADOW_TYPE_NONE);
gfx::Size size = bounds.size();
if (has_frame() &&
options.Get(switches::kUseContentSize, &use_content_size_) &&
use_content_size_)
size = ContentSizeToWindowSize(size);
window_->UpdateWindowIcon(); window_->UpdateWindowIcon();
window_->CenterWindow(bounds.size()); window_->CenterWindow(size);
Layout(); Layout();
} }
@ -440,42 +378,23 @@ gfx::Rect NativeWindowViews::GetBounds() {
return window_->GetWindowBoundsInScreen(); return window_->GetWindowBoundsInScreen();
} }
void NativeWindowViews::SetContentSize(const gfx::Size& size) {
if (!has_frame()) {
NativeWindow::SetSize(size);
return;
}
gfx::Rect bounds = window_->GetWindowBoundsInScreen();
bounds.set_size(size);
SetBounds(ContentBoundsToWindowBounds(bounds));
}
gfx::Size NativeWindowViews::GetContentSize() { gfx::Size NativeWindowViews::GetContentSize() {
if (!has_frame()) #if defined(OS_WIN)
return GetSize(); if (IsMinimized())
return NativeWindow::GetContentSize();
#endif
gfx::Size content_size = return web_view_->size();
window_->non_client_view()->frame_view()->GetBoundsForClientView().size();
if (menu_bar_ && menu_bar_visible_)
content_size.set_height(content_size.height() - kMenuBarHeight);
return content_size;
} }
void NativeWindowViews::SetMinimumSize(const gfx::Size& size) { void NativeWindowViews::SetContentSizeConstraints(
minimum_size_ = size; const extensions::SizeConstraints& size_constraints) {
} NativeWindow::SetContentSizeConstraints(size_constraints);
window_->OnSizeConstraintsChanged();
gfx::Size NativeWindowViews::GetMinimumSize() { #if defined(USE_X11)
return minimum_size_; if (resizable_)
} old_size_constraints_ = size_constraints;
#endif
void NativeWindowViews::SetMaximumSize(const gfx::Size& size) {
maximum_size_ = size;
}
gfx::Size NativeWindowViews::GetMaximumSize() {
return maximum_size_;
} }
void NativeWindowViews::SetResizable(bool resizable) { 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 // On Linux there is no "resizable" property of a window, we have to set
// both the minimum and maximum size to the window size to achieve it. // both the minimum and maximum size to the window size to achieve it.
if (resizable) { if (resizable) {
SetMaximumSize(gfx::Size()); SetContentSizeConstraints(old_size_constraints_);
SetMinimumSize(gfx::Size());
} else { } else {
SetMaximumSize(GetSize()); old_size_constraints_ = GetContentSizeConstraints();
SetMinimumSize(GetSize()); resizable_ = false;
gfx::Size content_size = GetContentSize();
SetContentSizeConstraints(
extensions::SizeConstraints(content_size, content_size));
} }
} }
#endif #endif
@ -610,8 +531,24 @@ void NativeWindowViews::SetMenu(ui::MenuModel* menu_model) {
if (!menu_bar_autohide_) { if (!menu_bar_autohide_) {
SetMenuBarVisibility(true); SetMenuBarVisibility(true);
if (use_content_size_) if (use_content_size_) {
// Enlarge the size constraints for the menu.
extensions::SizeConstraints constraints = GetContentSizeConstraints();
if (constraints.HasMinimumSize()) {
gfx::Size min_size = constraints.GetMinimumSize();
min_size.set_height(min_size.height() + kMenuBarHeight);
constraints.set_minimum_size(min_size);
}
if (constraints.HasMaximumSize()) {
gfx::Size max_size = constraints.GetMaximumSize();
max_size.set_height(max_size.height() + kMenuBarHeight);
constraints.set_maximum_size(max_size);
}
SetContentSizeConstraints(constraints);
// Resize the window to make sure content size is not changed.
SetContentSize(content_size); SetContentSize(content_size);
}
} }
} }
@ -814,103 +751,45 @@ void NativeWindowViews::OnWidgetMove() {
NotifyWindowMove(); NotifyWindowMove();
} }
#if defined(OS_WIN) gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) {
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) { if (!has_frame())
std::string command = AppCommandToString(command_id);
NotifyWindowExecuteWindowsCommand(command);
return false;
}
bool NativeWindowViews::PreHandleMSG(
UINT message, WPARAM w_param, LPARAM l_param, LRESULT* result) {
switch (message) {
case WM_COMMAND:
// Handle thumbar button click message.
if (HIWORD(w_param) == THBN_CLICKED)
return taskbar_host_.HandleThumbarButtonEvent(LOWORD(w_param));
return false;
case WM_SIZE:
// Handle window state change.
HandleSizeEvent(w_param, l_param);
return false;
default:
return false;
}
}
void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
// Here we handle the WM_SIZE event in order to figure out what is the current
// window state and notify the user accordingly.
switch (w_param) {
case SIZE_MAXIMIZED:
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
NotifyWindowMaximize();
break;
case SIZE_MINIMIZED:
last_window_state_ = ui::SHOW_STATE_MINIMIZED;
NotifyWindowMinimize();
break;
case SIZE_RESTORED:
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
// Window was resized so we save it's new size.
last_normal_size_ = GetSize();
} else {
switch (last_window_state_) {
case ui::SHOW_STATE_MAXIMIZED:
last_window_state_ = ui::SHOW_STATE_NORMAL;
// When the window is restored we resize it to the previous known
// normal size.
NativeWindow::SetSize(last_normal_size_);
NotifyWindowUnmaximize();
break;
case ui::SHOW_STATE_MINIMIZED:
if (IsFullscreen()) {
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
NotifyWindowEnterFullScreen();
} else {
last_window_state_ = ui::SHOW_STATE_NORMAL;
// When the window is restored we resize it to the previous known
// normal size.
NativeWindow::SetSize(last_normal_size_);
NotifyWindowRestore();
}
break;
}
}
break;
}
}
#endif
gfx::Size NativeWindowViews::WindowSizeToFramelessSize(
const gfx::Size& size) {
if (size.width() == 0 && size.height() == 0)
return size; return size;
gfx::Rect window_bounds = gfx::Rect(size); gfx::Size window_size(size);
if (use_content_size_) {
if (menu_bar_ && menu_bar_visible_) {
window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
}
} else if (has_frame()) {
#if defined(OS_WIN) #if defined(OS_WIN)
gfx::Size frame_size = gfx::win::ScreenToDIPRect( gfx::Rect dpi_bounds =
window_->non_client_view()->GetWindowBoundsForClientBounds( gfx::Rect(gfx::Point(), gfx::win::DIPToScreenSize(size));
gfx::Rect())).size(); gfx::Rect window_bounds = gfx::win::ScreenToDIPRect(
#else window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds));
gfx::Size frame_size = window_size = window_bounds.size();
window_->non_client_view()->GetWindowBoundsForClientBounds(
gfx::Rect()).size();
#endif #endif
window_bounds.set_height(window_bounds.height() - frame_size.height());
window_bounds.set_width(window_bounds.width() - frame_size.width());
}
return window_bounds.size(); if (menu_bar_ && menu_bar_visible_)
window_size.set_height(window_size.height() + kMenuBarHeight);
return window_size;
}
gfx::Size NativeWindowViews::WindowSizeToContentSize(const gfx::Size& size) {
if (!has_frame())
return size;
gfx::Size content_size(size);
#if defined(OS_WIN)
content_size = gfx::win::DIPToScreenSize(content_size);
RECT rect;
SetRectEmpty(&rect);
HWND hwnd = GetAcceleratedWidget();
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
AdjustWindowRectEx(&rect, style, FALSE, ex_style);
content_size.set_width(content_size.width() - (rect.right - rect.left));
content_size.set_height(content_size.height() - (rect.bottom - rect.top));
content_size = gfx::win::ScreenToDIPSize(content_size);
#endif
if (menu_bar_ && menu_bar_visible_)
content_size.set_height(content_size.height() - kMenuBarHeight);
return content_size;
} }
void NativeWindowViews::HandleKeyboardEvent( void NativeWindowViews::HandleKeyboardEvent(
@ -954,6 +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) { bool NativeWindowViews::AcceleratorPressed(const ui::Accelerator& accelerator) {
return accelerator_util::TriggerAcceleratorTableCommand( return accelerator_util::TriggerAcceleratorTableCommand(
&accelerator_table_, accelerator); &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() { ui::WindowShowState NativeWindowViews::GetRestoredState() {
if (IsMaximized()) if (IsMaximized())
return ui::SHOW_STATE_MAXIMIZED; return ui::SHOW_STATE_MAXIMIZED;

View file

@ -63,12 +63,9 @@ class NativeWindowViews : public NativeWindow,
bool IsFullscreen() const override; bool IsFullscreen() const override;
void SetBounds(const gfx::Rect& bounds) override; void SetBounds(const gfx::Rect& bounds) override;
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
void SetContentSize(const gfx::Size& size) override;
gfx::Size GetContentSize() override; gfx::Size GetContentSize() override;
void SetMinimumSize(const gfx::Size& size) override; void SetContentSizeConstraints(
gfx::Size GetMinimumSize() override; const extensions::SizeConstraints& size_constraints) override;
void SetMaximumSize(const gfx::Size& size) override;
gfx::Size GetMaximumSize() override;
void SetResizable(bool resizable) override; void SetResizable(bool resizable) override;
bool IsResizable() override; bool IsResizable() override;
void SetAlwaysOnTop(bool top) override; void SetAlwaysOnTop(bool top) override;
@ -94,8 +91,6 @@ class NativeWindowViews : public NativeWindow,
gfx::AcceleratedWidget GetAcceleratedWidget(); gfx::AcceleratedWidget GetAcceleratedWidget();
gfx::Size WindowSizeToFramelessSize(const gfx::Size& size);
views::Widget* widget() const { return window_.get(); } views::Widget* widget() const { return window_.get(); }
#if defined(OS_WIN) #if defined(OS_WIN)
@ -142,20 +137,20 @@ class NativeWindowViews : public NativeWindow,
#endif #endif
// NativeWindow: // NativeWindow:
gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override;
gfx::Size WindowSizeToContentSize(const gfx::Size& size) override;
void HandleKeyboardEvent( void HandleKeyboardEvent(
content::WebContents*, content::WebContents*,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;
// views::View: // views::View:
gfx::Size GetMinimumSize() override;
gfx::Size GetMaximumSize() override;
bool AcceleratorPressed(const ui::Accelerator& accelerator) override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
// Register accelerators supported by the menu model. // Register accelerators supported by the menu model.
void RegisterAccelerators(ui::MenuModel* menu_model); void RegisterAccelerators(ui::MenuModel* menu_model);
// Converts between client area and window area, since we include the menu bar
// in client area we need to substract/add menu bar's height in convertions.
gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& content_bounds);
// Returns the restore state for the window. // Returns the restore state for the window.
ui::WindowShowState GetRestoredState(); ui::WindowShowState GetRestoredState();
@ -172,6 +167,11 @@ class NativeWindowViews : public NativeWindow,
// Handles window state events. // Handles window state events.
scoped_ptr<WindowStateWatcher> window_state_watcher_; scoped_ptr<WindowStateWatcher> window_state_watcher_;
// The "resizable" flag on Linux is implemented by setting size constraints,
// we need to make sure size constraints are restored when window becomes
// resizable again.
extensions::SizeConstraints old_size_constraints_;
#elif defined(OS_WIN) #elif defined(OS_WIN)
// Weak ref. // Weak ref.
AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_; AtomDesktopWindowTreeHostWin* atom_desktop_window_tree_host_win_;
@ -197,8 +197,6 @@ class NativeWindowViews : public NativeWindow,
bool use_content_size_; bool use_content_size_;
bool resizable_; bool resizable_;
std::string title_; std::string title_;
gfx::Size minimum_size_;
gfx::Size maximum_size_;
gfx::Size widget_size_; gfx::Size widget_size_;
DISALLOW_COPY_AND_ASSIGN(NativeWindowViews); DISALLOW_COPY_AND_ASSIGN(NativeWindowViews);

View 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

View file

@ -104,11 +104,11 @@ gfx::Size FramelessView::GetPreferredSize() const {
} }
gfx::Size FramelessView::GetMinimumSize() const { gfx::Size FramelessView::GetMinimumSize() const {
return window_->GetMinimumSize(); return window_->GetContentSizeConstraints().GetMinimumSize();
} }
gfx::Size FramelessView::GetMaximumSize() const { gfx::Size FramelessView::GetMaximumSize() const {
return window_->GetMaximumSize(); return window_->GetContentSizeConstraints().GetMaximumSize();
} }
const char* FramelessView::GetClassName() const { const char* FramelessView::GetClassName() const {

View file

@ -4,7 +4,7 @@
#include "atom/browser/ui/views/native_frame_view.h" #include "atom/browser/ui/views/native_frame_view.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window.h"
namespace atom { namespace atom {
@ -14,8 +14,7 @@ const char kViewClassName[] = "AtomNativeFrameView";
} // namespace } // namespace
NativeFrameView::NativeFrameView(NativeWindowViews* window, NativeFrameView::NativeFrameView(NativeWindow* window, views::Widget* widget)
views::Widget* widget)
: views::NativeFrameView(widget), : views::NativeFrameView(widget),
window_(window) { window_(window) {
} }

View file

@ -9,13 +9,13 @@
namespace atom { namespace atom {
class NativeWindowViews; class NativeWindow;
// Like the views::NativeFrameView, but returns the min/max size from the // Like the views::NativeFrameView, but returns the min/max size from the
// NativeWindowViews. // NativeWindowViews.
class NativeFrameView : public views::NativeFrameView { class NativeFrameView : public views::NativeFrameView {
public: public:
NativeFrameView(NativeWindowViews* window, views::Widget* widget); NativeFrameView(NativeWindow* window, views::Widget* widget);
protected: protected:
// views::View: // views::View:
@ -24,7 +24,7 @@ class NativeFrameView : public views::NativeFrameView {
const char* GetClassName() const override; const char* GetClassName() const override;
private: private:
NativeWindowViews* window_; // weak ref. NativeWindow* window_; // weak ref.
DISALLOW_COPY_AND_ASSIGN(NativeFrameView); DISALLOW_COPY_AND_ASSIGN(NativeFrameView);
}; };

View file

@ -5,7 +5,6 @@
#include "atom/browser/ui/views/win_frame_view.h" #include "atom/browser/ui/views/win_frame_view.h"
#include "atom/browser/native_window_views.h" #include "atom/browser/native_window_views.h"
#include "ui/gfx/win/dpi.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
#include "ui/views/win/hwnd_util.h" #include "ui/views/win/hwnd_util.h"
@ -39,18 +38,6 @@ int WinFrameView::NonClientHitTest(const gfx::Point& point) {
return FramelessView::NonClientHitTest(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 { const char* WinFrameView::GetClassName() const {
return kViewClassName; return kViewClassName;
} }

View file

@ -20,8 +20,6 @@ class WinFrameView : public FramelessView {
int NonClientHitTest(const gfx::Point& point) override; int NonClientHitTest(const gfx::Point& point) override;
// views::View: // views::View:
gfx::Size GetMinimumSize() const override;
gfx::Size GetMaximumSize() const override;
const char* GetClassName() const override; const char* GetClassName() const override;
private: private:

View file

@ -10,9 +10,10 @@ namespace atom {
ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) { ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) {
*shifted = false; *shifted = false;
switch (c) { switch (c) {
case 8: case 0x7F: return ui::VKEY_BACK; case 0x08: return ui::VKEY_BACK;
case 9: return ui::VKEY_TAB; case 0x7F: return ui::VKEY_DELETE;
case 0xD: case 3: return ui::VKEY_RETURN; case 0x09: return ui::VKEY_TAB;
case 0x0D: return ui::VKEY_RETURN;
case 0x1B: return ui::VKEY_ESCAPE; case 0x1B: return ui::VKEY_ESCAPE;
case ' ': return ui::VKEY_SPACE; case ' ': return ui::VKEY_SPACE;

View file

@ -61,7 +61,7 @@ struct Converter<blink::WebInputEvent::Type> {
else if (type == "mousewheel") else if (type == "mousewheel")
*out = blink::WebInputEvent::MouseWheel; *out = blink::WebInputEvent::MouseWheel;
else if (type == "keydown") else if (type == "keydown")
*out = blink::WebInputEvent::KeyDown; *out = blink::WebInputEvent::RawKeyDown;
else if (type == "keyup") else if (type == "keyup")
*out = blink::WebInputEvent::KeyUp; *out = blink::WebInputEvent::KeyUp;
else if (type == "char") else if (type == "char")

View file

@ -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

View file

@ -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_

View file

@ -142,7 +142,7 @@ Returns a boolean whether the image is empty.
Returns the size of the image. 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)` ### `image.setTemplateImage(option)`

View file

@ -21,9 +21,11 @@ the global scope when node integration is turned off:
```js ```js
// preload.js // preload.js
var _setImmediate = setImmediate;
var _clearImmediate = clearImmediate;
process.once('loaded', function() { process.once('loaded', function() {
global.setImmediate = setImmediate; global.setImmediate = _setImmediate;
global.clearImmediate = clearImmediate; global.clearImmediate = _clearImmediate;
}); });
``` ```

View file

@ -47,7 +47,7 @@ app.on('ready', function() {
if (externalDisplay) { if (externalDisplay) {
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
x: externalDisplay.bounds.x + 50, x: externalDisplay.bounds.x + 50,
y: externalDisplay.bounds.y + 50, y: externalDisplay.bounds.y + 50
}); });
} }
}); });

View file

@ -2,7 +2,7 @@
Electron enables you to create desktop applications with pure JavaScript by Electron enables you to create desktop applications with pure JavaScript by
providing a runtime with rich native (operating system) APIs. You could see it 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. instead of web servers.
This doesn't mean Electron is a JavaScript binding to graphical user interface 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__. its own process, which is called __the renderer process__.
In normal browsers, web pages usually run in a sandboxed environment and are not 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 allowed access to native resources. Electron users, however, have the power to
io.js APIs in web pages allowing lower level operating system interactions. use Node.js APIs in web pages allowing lower level operating system
interactions.
### Differences Between Main Process and Renderer Process ### Differences Between Main Process and Renderer Process
@ -129,7 +130,7 @@ Finally the `index.html` is the web page you want to show:
</head> </head>
<body> <body>
<h1>Hello World!</h1> <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>. and Electron <script>document.write(process.versions['electron'])</script>.
</body> </body>
</html> </html>

View file

@ -4,19 +4,27 @@ Following platforms are supported by Electron:
### OS X ### 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
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 ### 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 * Ubuntu 12.04 and later
* Fedora 21 * Fedora 21

View file

@ -6,16 +6,17 @@ the location of Electron's headers when building native modules.
## Native Node Module Compatibility ## Native Node Module Compatibility
Since Node v0.11.x there were vital changes in the V8 API. So generally all Native modules might break when Node starts using a new version of V8.
native modules written for Node v0.10.x won't work for newer Node or io.js To make sure the module you're interested in will work with Electron, you should
versions. And because Electron internally uses __io.js v3.1.0__, it has the check if it supports the internal Node version used by Electron.
same problem. 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, Consider using [NAN](https://github.com/nodejs/nan/) for your own modules, since
[many modules](https://www.npmjs.org/browse/depended/nan) do support both now. it makes it easier to support multiple versions of Node. It's also helpful for
For old modules that only support Node v0.10.x, you should use the porting old modules to newer versions of Node so they can work with Electron.
[nan](https://github.com/rvagg/nan) module to port it to v0.11.x or later
versions of Node or io.js.
## How to Install Native Modules ## How to Install Native Modules

View file

@ -154,6 +154,7 @@
'atom/browser/mac/atom_application_delegate.mm', 'atom/browser/mac/atom_application_delegate.mm',
'atom/browser/native_window.cc', 'atom/browser/native_window.cc',
'atom/browser/native_window.h', 'atom/browser/native_window.h',
'atom/browser/native_window_views_win.cc',
'atom/browser/native_window_views.cc', 'atom/browser/native_window_views.cc',
'atom/browser/native_window_views.h', 'atom/browser/native_window_views.h',
'atom/browser/native_window_mac.h', 'atom/browser/native_window_mac.h',
@ -429,6 +430,8 @@
'chromium_src/chrome/renderer/tts_dispatcher.cc', 'chromium_src/chrome/renderer/tts_dispatcher.cc',
'chromium_src/chrome/renderer/tts_dispatcher.h', 'chromium_src/chrome/renderer/tts_dispatcher.h',
'chromium_src/chrome/utility/utility_message_handler.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_loader.cc',
'chromium_src/library_loaders/libspeechd.h', 'chromium_src/library_loaders/libspeechd.h',
'chromium_src/net/test/embedded_test_server/stream_listen_socket.cc', 'chromium_src/net/test/embedded_test_server/stream_listen_socket.cc',

View file

@ -4,10 +4,17 @@ https = require 'https'
path = require 'path' path = require 'path'
ws = require 'ws' ws = require 'ws'
remote = require 'remote' remote = require 'remote'
BrowserWindow = remote.require 'browser-window'
describe 'chromium feature', -> describe 'chromium feature', ->
fixtures = path.resolve __dirname, 'fixtures' fixtures = path.resolve __dirname, 'fixtures'
listener = null
afterEach ->
if listener?
window.removeEventListener 'message', listener
listener = null
xdescribe 'heap snapshot', -> xdescribe 'heap snapshot', ->
it 'does not crash', -> it 'does not crash', ->
process.atomBinding('v8_util').takeHeapSnapshot() process.atomBinding('v8_util').takeHeapSnapshot()
@ -24,20 +31,17 @@ describe 'chromium feature', ->
$.get "http://127.0.0.1:#{port}" $.get "http://127.0.0.1:#{port}"
describe 'document.hidden', -> describe 'document.hidden', ->
BrowserWindow = remote.require 'browser-window'
ipc = remote.require 'ipc'
url = "file://#{fixtures}/pages/document-hidden.html" url = "file://#{fixtures}/pages/document-hidden.html"
w = null w = null
afterEach -> afterEach ->
w?.destroy() w?.destroy()
ipc.removeAllListeners 'hidden'
it 'is set correctly when window is not shown', (done) -> it 'is set correctly when window is not shown', (done) ->
ipc.once 'hidden', (event, hidden) ->
assert hidden
done()
w = new BrowserWindow(show:false) w = new BrowserWindow(show:false)
w.webContents.on 'ipc-message', (event, args) ->
assert.deepEqual args, ['hidden', true]
done()
w.loadUrl url w.loadUrl url
describe 'navigator.webkitGetUserMedia', -> describe 'navigator.webkitGetUserMedia', ->
@ -62,19 +66,17 @@ describe 'chromium feature', ->
it 'accepts "node-integration" as feature', (done) -> it 'accepts "node-integration" as feature', (done) ->
listener = (event) -> listener = (event) ->
window.removeEventListener 'message', listener
b.close()
assert.equal event.data, 'undefined' assert.equal event.data, 'undefined'
b.close()
done() done()
window.addEventListener 'message', listener window.addEventListener 'message', listener
b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no' b = window.open "file://#{fixtures}/pages/window-opener-node.html", '', 'node-integration=no,show=no'
it 'inherit options of parent window', (done) -> it 'inherit options of parent window', (done) ->
listener = (event) -> listener = (event) ->
window.removeEventListener 'message', listener
b.close()
size = remote.getCurrentWindow().getSize() size = remote.getCurrentWindow().getSize()
assert.equal event.data, "size: #{size.width} #{size.height}" assert.equal event.data, "size: #{size.width} #{size.height}"
b.close()
done() done()
window.addEventListener 'message', listener window.addEventListener 'message', listener
b = window.open "file://#{fixtures}/pages/window-open-size.html", '', 'show=no' b = window.open "file://#{fixtures}/pages/window-open-size.html", '', 'show=no'
@ -82,26 +84,25 @@ describe 'chromium feature', ->
describe 'window.opener', -> describe 'window.opener', ->
@timeout 10000 @timeout 10000
ipc = remote.require 'ipc'
url = "file://#{fixtures}/pages/window-opener.html" url = "file://#{fixtures}/pages/window-opener.html"
w = null w = null
afterEach -> afterEach ->
w?.destroy() w?.destroy()
ipc.removeAllListeners 'opener'
it 'is null for main window', (done) -> 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 = new BrowserWindow(show: false)
w.webContents.on 'ipc-message', (event, args) ->
assert.deepEqual args, ['opener', null]
done()
w.loadUrl url w.loadUrl url
it 'is not null for window opened by window.open', (done) -> 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() b.close()
done(if opener isnt null then undefined else opener) done()
window.addEventListener 'message', listener
b = window.open url, '', 'show=no' b = window.open url, '', 'show=no'
describe 'window.opener.postMessage', -> describe 'window.opener.postMessage', ->

View file

@ -1,7 +1,10 @@
<html> <html>
<body> <body>
<script type="text/javascript" charset="utf-8"> <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> </script>
</body> </body>
</html> </html>

2
vendor/brightray vendored

@ -1 +1 @@
Subproject commit c44f99278bc4f6823f81b6f3a8d75881d697fd01 Subproject commit c25b9b27845a308e6a6a5966dad057d721b1f3d1