Merge pull request #6654 from electron/content-bounds

Add BrowserWindow.get/setContentBounds()
This commit is contained in:
Cheng Zhao 2016-08-05 17:23:24 +09:00 committed by GitHub
commit 8a33464d41
10 changed files with 153 additions and 58 deletions

View file

@ -366,6 +366,16 @@ gfx::Rect Window::GetBounds() {
return window_->GetBounds(); return window_->GetBounds();
} }
void Window::SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args) {
bool animate = false;
args->GetNext(&animate);
window_->SetContentBounds(bounds, animate);
}
gfx::Rect Window::GetContentBounds() {
return window_->GetContentBounds();
}
void Window::SetSize(int width, int height, mate::Arguments* args) { void Window::SetSize(int width, int height, mate::Arguments* args) {
bool animate = false; bool animate = false;
args->GetNext(&animate); args->GetNext(&animate);
@ -785,6 +795,8 @@ void Window::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setBounds", &Window::SetBounds) .SetMethod("setBounds", &Window::SetBounds)
.SetMethod("getSize", &Window::GetSize) .SetMethod("getSize", &Window::GetSize)
.SetMethod("setSize", &Window::SetSize) .SetMethod("setSize", &Window::SetSize)
.SetMethod("getContentBounds", &Window::GetContentBounds)
.SetMethod("setContentBounds", &Window::SetContentBounds)
.SetMethod("getContentSize", &Window::GetContentSize) .SetMethod("getContentSize", &Window::GetContentSize)
.SetMethod("setContentSize", &Window::SetContentSize) .SetMethod("setContentSize", &Window::SetContentSize)
.SetMethod("setMinimumSize", &Window::SetMinimumSize) .SetMethod("setMinimumSize", &Window::SetMinimumSize)

View file

@ -112,6 +112,8 @@ class Window : public mate::TrackableObject<Window>,
std::vector<int> GetSize(); std::vector<int> GetSize();
void SetContentSize(int width, int height, mate::Arguments* args); void SetContentSize(int width, int height, mate::Arguments* args);
std::vector<int> GetContentSize(); std::vector<int> GetContentSize();
void SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args);
gfx::Rect GetContentBounds();
void SetMinimumSize(int width, int height); void SetMinimumSize(int width, int height);
std::vector<int> GetMinimumSize(); std::vector<int> GetMinimumSize();
void SetMaximumSize(int width, int height); void SetMaximumSize(int width, int height);

View file

@ -219,34 +219,50 @@ gfx::Point NativeWindow::GetPosition() {
} }
void NativeWindow::SetContentSize(const gfx::Size& size, bool animate) { void NativeWindow::SetContentSize(const gfx::Size& size, bool animate) {
SetSize(ContentSizeToWindowSize(size), animate); SetSize(ContentBoundsToWindowBounds(gfx::Rect(size)).size(), animate);
} }
gfx::Size NativeWindow::GetContentSize() { gfx::Size NativeWindow::GetContentSize() {
return WindowSizeToContentSize(GetSize()); return GetContentBounds().size();
}
void NativeWindow::SetContentBounds(const gfx::Rect& bounds, bool animate) {
SetBounds(ContentBoundsToWindowBounds(bounds), animate);
}
gfx::Rect NativeWindow::GetContentBounds() {
return WindowBoundsToContentBounds(GetBounds());
} }
void NativeWindow::SetSizeConstraints( void NativeWindow::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) { const extensions::SizeConstraints& window_constraints) {
extensions::SizeConstraints content_constraints(GetContentSizeConstraints()); extensions::SizeConstraints content_constraints(GetContentSizeConstraints());
if (window_constraints.HasMaximumSize()) if (window_constraints.HasMaximumSize()) {
content_constraints.set_maximum_size( gfx::Rect max_bounds = WindowBoundsToContentBounds(
WindowSizeToContentSize(window_constraints.GetMaximumSize())); gfx::Rect(window_constraints.GetMaximumSize()));
if (window_constraints.HasMinimumSize()) content_constraints.set_maximum_size(max_bounds.size());
content_constraints.set_minimum_size( }
WindowSizeToContentSize(window_constraints.GetMinimumSize())); if (window_constraints.HasMinimumSize()) {
gfx::Rect min_bounds = WindowBoundsToContentBounds(
gfx::Rect(window_constraints.GetMinimumSize()));
content_constraints.set_minimum_size(min_bounds.size());
}
SetContentSizeConstraints(content_constraints); SetContentSizeConstraints(content_constraints);
} }
extensions::SizeConstraints NativeWindow::GetSizeConstraints() { extensions::SizeConstraints NativeWindow::GetSizeConstraints() {
extensions::SizeConstraints content_constraints = GetContentSizeConstraints(); extensions::SizeConstraints content_constraints = GetContentSizeConstraints();
extensions::SizeConstraints window_constraints; extensions::SizeConstraints window_constraints;
if (content_constraints.HasMaximumSize()) if (content_constraints.HasMaximumSize()) {
window_constraints.set_maximum_size( gfx::Rect max_bounds = ContentBoundsToWindowBounds(
ContentSizeToWindowSize(content_constraints.GetMaximumSize())); gfx::Rect(content_constraints.GetMaximumSize()));
if (content_constraints.HasMinimumSize()) window_constraints.set_maximum_size(max_bounds.size());
window_constraints.set_minimum_size( }
ContentSizeToWindowSize(content_constraints.GetMinimumSize())); if (content_constraints.HasMinimumSize()) {
gfx::Rect min_bounds = ContentBoundsToWindowBounds(
gfx::Rect(content_constraints.GetMinimumSize()));
window_constraints.set_minimum_size(min_bounds.size());
}
return window_constraints; return window_constraints;
} }

View file

@ -91,6 +91,8 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::Point GetPosition(); virtual gfx::Point GetPosition();
virtual void SetContentSize(const gfx::Size& size, bool animate = false); virtual void SetContentSize(const gfx::Size& size, bool animate = false);
virtual gfx::Size GetContentSize(); virtual gfx::Size GetContentSize();
virtual void SetContentBounds(const gfx::Rect& bounds, bool animate = false);
virtual gfx::Rect GetContentBounds();
virtual void SetSizeConstraints( virtual void SetSizeConstraints(
const extensions::SizeConstraints& size_constraints); const extensions::SizeConstraints& size_constraints);
virtual extensions::SizeConstraints GetSizeConstraints(); virtual extensions::SizeConstraints GetSizeConstraints();
@ -238,9 +240,9 @@ class NativeWindow : public base::SupportsUserData,
std::unique_ptr<SkRegion> DraggableRegionsToSkRegion( std::unique_ptr<SkRegion> DraggableRegionsToSkRegion(
const std::vector<DraggableRegion>& regions); const std::vector<DraggableRegion>& regions);
// Converts between content size to window size. // Converts between content bounds and window bounds.
virtual gfx::Size ContentSizeToWindowSize(const gfx::Size& size) = 0; virtual gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) = 0;
virtual gfx::Size WindowSizeToContentSize(const gfx::Size& size) = 0; virtual gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) = 0;
// Called when the window needs to update its draggable region. // Called when the window needs to update its draggable region.
virtual void UpdateDraggableRegions( virtual void UpdateDraggableRegions(

View file

@ -114,8 +114,8 @@ class NativeWindowMac : public NativeWindow {
private: private:
// NativeWindow: // NativeWindow:
gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override; gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds);
gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds);
void UpdateDraggableRegions( void UpdateDraggableRegions(
const std::vector<DraggableRegion>& regions) override; const std::vector<DraggableRegion>& regions) override;

View file

@ -1043,22 +1043,30 @@ std::vector<gfx::Rect> NativeWindowMac::CalculateNonDraggableRegions(
return result; return result;
} }
gfx::Size NativeWindowMac::ContentSizeToWindowSize(const gfx::Size& size) { gfx::Rect NativeWindowMac::ContentBoundsToWindowBounds(
if (!has_frame()) const gfx::Rect& bounds) {
return size; if (has_frame()) {
gfx::Rect window_bounds(
NSRect content = NSMakeRect(0, 0, size.width(), size.height()); [window_ frameRectForContentRect:bounds.ToCGRect()]);
NSRect frame = [window_ frameRectForContentRect:content]; int frame_height = window_bounds.height() - bounds.height();
return gfx::Size(frame.size); window_bounds.set_y(window_bounds.y() - frame_height);
return window_bounds;
} else {
return bounds;
}
} }
gfx::Size NativeWindowMac::WindowSizeToContentSize(const gfx::Size& size) { gfx::Rect NativeWindowMac::WindowBoundsToContentBounds(
if (!has_frame()) const gfx::Rect& bounds) {
return size; if (has_frame()) {
gfx::Rect content_bounds(
NSRect frame = NSMakeRect(0, 0, size.width(), size.height()); [window_ contentRectForFrameRect:bounds.ToCGRect()]);
NSRect content = [window_ contentRectForFrameRect:frame]; int frame_height = bounds.height() - content_bounds.height();
return gfx::Size(content.size); content_bounds.set_y(content_bounds.y() + frame_height);
return content_bounds;
} else {
return bounds;
}
} }
void NativeWindowMac::UpdateDraggableRegions( void NativeWindowMac::UpdateDraggableRegions(

View file

@ -316,7 +316,7 @@ NativeWindowViews::NativeWindowViews(
if (has_frame() && if (has_frame() &&
options.Get(options::kUseContentSize, &use_content_size_) && options.Get(options::kUseContentSize, &use_content_size_) &&
use_content_size_) use_content_size_)
size = ContentSizeToWindowSize(size); size = ContentBoundsToWindowBounds(gfx::Rect(size)).size();
window_->CenterWindow(size); window_->CenterWindow(size);
Layout(); Layout();
@ -544,6 +544,10 @@ gfx::Rect NativeWindowViews::GetBounds() {
return window_->GetWindowBoundsInScreen(); return window_->GetWindowBoundsInScreen();
} }
gfx::Rect NativeWindowViews::GetContentBounds() {
return web_view_->GetBoundsInScreen();
}
gfx::Size NativeWindowViews::GetContentSize() { gfx::Size NativeWindowViews::GetContentSize() {
#if defined(OS_WIN) #if defined(OS_WIN)
if (IsMinimized()) if (IsMinimized())
@ -1146,47 +1150,53 @@ void NativeWindowViews::OnWidgetMove() {
NotifyWindowMove(); NotifyWindowMove();
} }
gfx::Size NativeWindowViews::ContentSizeToWindowSize(const gfx::Size& size) { gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds(
const gfx::Rect& bounds) {
if (!has_frame()) if (!has_frame())
return size; return bounds;
gfx::Size window_size(size); gfx::Rect window_bounds(bounds);
#if defined(OS_WIN) #if defined(OS_WIN)
HWND hwnd = GetAcceleratedWidget(); HWND hwnd = GetAcceleratedWidget();
gfx::Rect dpi_bounds = gfx::Rect( gfx::Rect dpi_bounds = display::win::ScreenWin::DIPToScreenRect(hwnd, bounds);
gfx::Point(), display::win::ScreenWin::DIPToScreenSize(hwnd, size)); window_bounds = display::win::ScreenWin::ScreenToDIPRect(
gfx::Rect window_bounds = display::win::ScreenWin::ScreenToDIPRect(
hwnd, hwnd,
window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds)); window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds));
window_size = window_bounds.size();
#endif #endif
if (menu_bar_ && menu_bar_visible_) if (menu_bar_ && menu_bar_visible_) {
window_size.set_height(window_size.height() + kMenuBarHeight); window_bounds.set_y(window_bounds.y() - kMenuBarHeight);
return window_size; window_bounds.set_height(window_bounds.height() + kMenuBarHeight);
}
return window_bounds;
} }
gfx::Size NativeWindowViews::WindowSizeToContentSize(const gfx::Size& size) { gfx::Rect NativeWindowViews::WindowBoundsToContentBounds(
const gfx::Rect& bounds) {
if (!has_frame()) if (!has_frame())
return size; return bounds;
gfx::Size content_size(size); gfx::Rect content_bounds(bounds);
#if defined(OS_WIN) #if defined(OS_WIN)
HWND hwnd = GetAcceleratedWidget(); HWND hwnd = GetAcceleratedWidget();
content_size = display::win::ScreenWin::DIPToScreenSize(hwnd, content_size); content_bounds.set_size(
display::win::ScreenWin::DIPToScreenSize(hwnd, content_bounds.size()));
RECT rect; RECT rect;
SetRectEmpty(&rect); SetRectEmpty(&rect);
DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); DWORD style = ::GetWindowLong(hwnd, GWL_STYLE);
DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
AdjustWindowRectEx(&rect, style, FALSE, ex_style); AdjustWindowRectEx(&rect, style, FALSE, ex_style);
content_size.set_width(content_size.width() - (rect.right - rect.left)); content_bounds.set_width(content_bounds.width() - (rect.right - rect.left));
content_size.set_height(content_size.height() - (rect.bottom - rect.top)); content_bounds.set_height(content_bounds.height() - (rect.bottom - rect.top));
content_size = display::win::ScreenWin::ScreenToDIPSize(hwnd, content_size); content_bounds.set_size(
display::win::ScreenWin::ScreenToDIPSize(hwnd, content_bounds.size()));
#endif #endif
if (menu_bar_ && menu_bar_visible_) if (menu_bar_ && menu_bar_visible_) {
content_size.set_height(content_size.height() - kMenuBarHeight); content_bounds.set_y(content_bounds.y() + kMenuBarHeight);
return content_size; content_bounds.set_height(content_bounds.height() - kMenuBarHeight);
}
return content_bounds;
} }
void NativeWindowViews::HandleKeyboardEvent( void NativeWindowViews::HandleKeyboardEvent(

View file

@ -68,6 +68,7 @@ class NativeWindowViews : public NativeWindow,
bool IsFullscreen() const override; bool IsFullscreen() const override;
void SetBounds(const gfx::Rect& bounds, bool animate) override; void SetBounds(const gfx::Rect& bounds, bool animate) override;
gfx::Rect GetBounds() override; gfx::Rect GetBounds() override;
gfx::Rect GetContentBounds() override;
gfx::Size GetContentSize() override; gfx::Size GetContentSize() override;
void SetContentSizeConstraints( void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) override; const extensions::SizeConstraints& size_constraints) override;
@ -164,8 +165,8 @@ class NativeWindowViews : public NativeWindow,
#endif #endif
// NativeWindow: // NativeWindow:
gfx::Size ContentSizeToWindowSize(const gfx::Size& size) override; gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) override;
gfx::Size WindowSizeToContentSize(const gfx::Size& size) override; gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) override;
void HandleKeyboardEvent( void HandleKeyboardEvent(
content::WebContents*, content::WebContents*,
const content::NativeWebKeyboardEvent& event) override; const content::NativeWebKeyboardEvent& event) override;

View file

@ -669,6 +669,23 @@ Resizes and moves the window to `width`, `height`, `x`, `y`.
Returns an object that contains window's width, height, x and y values. Returns an object that contains window's width, height, x and y values.
#### `win.setContentBounds(options[, animate])`
* `options` Object
* `x` Integer
* `y` Integer
* `width` Integer
* `height` Integer
* `animate` Boolean (optional) _macOS_
Resizes and moves the window's client area (e.g. the web page) to
`width`, `height`, `x`, `y`.
#### `win.getContentBounds()`
Returns an object that contains the window's client area (e.g. the web page)
width, height, x and y values.
#### `win.setSize(width, height[, animate])` #### `win.setSize(width, height[, animate])`
* `width` Integer * `width` Integer

View file

@ -334,7 +334,7 @@ describe('browser-window module', function () {
assert.equal(after[1], size[1]) assert.equal(after[1], size[1])
}) })
it('works for framless window', function () { it('works for a frameless window', function () {
w.destroy() w.destroy()
w = new BrowserWindow({ w = new BrowserWindow({
show: false, show: false,
@ -350,6 +350,33 @@ describe('browser-window module', function () {
}) })
}) })
describe('BrowserWindow.setContentBounds(bounds)', function () {
it('sets the content size and position', function (done) {
var bounds = {x: 10, y: 10, width: 250, height: 250}
w.once('resize', function () {
assert.deepEqual(w.getContentBounds(), bounds)
done()
})
w.setContentBounds(bounds)
})
it('works for a frameless window', function (done) {
w.destroy()
w = new BrowserWindow({
show: false,
frame: false,
width: 300,
height: 300
})
var bounds = {x: 10, y: 10, width: 250, height: 250}
w.once('resize', function () {
assert.deepEqual(w.getContentBounds(), bounds)
done()
})
w.setContentBounds(bounds)
})
})
describe('BrowserWindow.setProgressBar(progress)', function () { describe('BrowserWindow.setProgressBar(progress)', function () {
it('sets the progress', function () { it('sets the progress', function () {
assert.doesNotThrow(function () { assert.doesNotThrow(function () {
@ -392,7 +419,7 @@ describe('browser-window module', function () {
assert.equal(size[1], 400) assert.equal(size[1], 400)
}) })
it('works for framless window', function () { it('works for a frameless window', function () {
w.destroy() w.destroy()
w = new BrowserWindow({ w = new BrowserWindow({
show: false, show: false,