Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: BrowserWindow.getNormalBounds() #13290

Merged
merged 18 commits into from Aug 24, 2018
10 changes: 10 additions & 0 deletions atom/browser/api/atom_api_top_level_window.cc
Expand Up @@ -358,6 +358,14 @@ gfx::Rect TopLevelWindow::GetBounds() {
return window_->GetBounds();
}

bool TopLevelWindow::IsNormal() {
return window_->IsNormal();
}

gfx::Rect TopLevelWindow::GetNormalBounds() {
return window_->GetNormalBounds();
}

void TopLevelWindow::SetContentBounds(const gfx::Rect& bounds,
mate::Arguments* args) {
bool animate = false;
Expand Down Expand Up @@ -949,6 +957,8 @@ void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("isFullScreen", &TopLevelWindow::IsFullscreen)
.SetMethod("setBounds", &TopLevelWindow::SetBounds)
.SetMethod("getBounds", &TopLevelWindow::GetBounds)
.SetMethod("isNormal", &TopLevelWindow::IsNormal)
.SetMethod("getNormalBounds", &TopLevelWindow::GetNormalBounds)
.SetMethod("setSize", &TopLevelWindow::SetSize)
.SetMethod("getSize", &TopLevelWindow::GetSize)
.SetMethod("setContentBounds", &TopLevelWindow::SetContentBounds)
Expand Down
2 changes: 2 additions & 0 deletions atom/browser/api/atom_api_top_level_window.h
Expand Up @@ -108,6 +108,8 @@ class TopLevelWindow : public mate::TrackableObject<TopLevelWindow>,
std::vector<int> GetContentSize();
void SetContentBounds(const gfx::Rect& bounds, mate::Arguments* args);
gfx::Rect GetContentBounds();
bool IsNormal();
gfx::Rect GetNormalBounds();
void SetMinimumSize(int width, int height);
std::vector<int> GetMinimumSize();
void SetMaximumSize(int width, int height);
Expand Down
4 changes: 4 additions & 0 deletions atom/browser/native_window.cc
Expand Up @@ -208,6 +208,10 @@ gfx::Rect NativeWindow::GetContentBounds() {
return WindowBoundsToContentBounds(GetBounds());
}

bool NativeWindow::IsNormal() {
return !IsMinimized() && !IsMaximized() && !IsFullscreen();
}

void NativeWindow::SetSizeConstraints(
const extensions::SizeConstraints& window_constraints) {
extensions::SizeConstraints content_constraints(GetContentSizeConstraints());
Expand Down
2 changes: 2 additions & 0 deletions atom/browser/native_window.h
Expand Up @@ -87,6 +87,8 @@ class NativeWindow : public base::SupportsUserData,
virtual gfx::Size GetContentSize();
virtual void SetContentBounds(const gfx::Rect& bounds, bool animate = false);
virtual gfx::Rect GetContentBounds();
virtual bool IsNormal();
virtual gfx::Rect GetNormalBounds() = 0;
virtual void SetSizeConstraints(
const extensions::SizeConstraints& size_constraints);
virtual extensions::SizeConstraints GetSizeConstraints() const;
Expand Down
2 changes: 2 additions & 0 deletions atom/browser/native_window_mac.h
Expand Up @@ -52,6 +52,8 @@ class NativeWindowMac : public NativeWindow {
bool IsFullscreen() const override;
void SetBounds(const gfx::Rect& bounds, bool animate = false) override;
gfx::Rect GetBounds() override;
bool IsNormal() override;
gfx::Rect GetNormalBounds() override;
void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) override;
void SetResizable(bool resizable) override;
Expand Down
34 changes: 33 additions & 1 deletion atom/browser/native_window_mac.mm
Expand Up @@ -469,6 +469,8 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
// Default content view.
SetContentView(new views::View());
AddContentViewLayers();

original_frame_ = [window_ frame];
}

NativeWindowMac::~NativeWindowMac() {
Expand Down Expand Up @@ -594,6 +596,9 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
if (IsMaximized())
return;

// Take note of the current window size
if (IsNormal())
original_frame_ = [window_ frame];
[window_ zoom:nil];
}

Expand All @@ -618,6 +623,12 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

void NativeWindowMac::Minimize() {
if (IsMinimized())
return;

// Take note of the current window size
if (IsNormal())
original_frame_ = [window_ frame];
[window_ miniaturize:nil];
}

Expand All @@ -633,6 +644,9 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
if (fullscreen == IsFullscreen())
return;

// Take note of the current window size
if (IsNormal())
original_frame_ = [window_ frame];
[window_ toggleFullScreenMode:nil];
}

Expand Down Expand Up @@ -668,6 +682,23 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
return bounds;
}

bool NativeWindowMac::IsNormal() {
return NativeWindow::IsNormal() && !IsSimpleFullScreen();
}

gfx::Rect NativeWindowMac::GetNormalBounds() {
if (IsNormal()) {
return GetBounds();
}
NSRect frame = original_frame_;
gfx::Rect bounds(frame.origin.x, 0, NSWidth(frame), NSHeight(frame));
NSScreen* screen = [[NSScreen screens] firstObject];
bounds.set_y(NSHeight([screen frame]) - NSMaxY(frame));
return bounds;
// Works on OS_WIN !
// return widget()->GetRestoredBounds();
}

void NativeWindowMac::SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) {
auto convertSize = [this](const gfx::Size& size) {
Expand Down Expand Up @@ -860,7 +891,8 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
is_simple_fullscreen_ = true;

// Take note of the current window size
original_frame_ = [window frame];
if (IsNormal())
original_frame_ = [window_ frame];

simple_fullscreen_options_ = [NSApp currentSystemPresentationOptions];
simple_fullscreen_mask_ = [window styleMask];
Expand Down
4 changes: 4 additions & 0 deletions atom/browser/native_window_views.cc
Expand Up @@ -562,6 +562,10 @@ gfx::Size NativeWindowViews::GetContentSize() {
return content_view() ? content_view()->size() : gfx::Size();
}

gfx::Rect NativeWindowViews::GetNormalBounds() {
return widget()->GetRestoredBounds();
}

void NativeWindowViews::SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) {
NativeWindow::SetContentSizeConstraints(size_constraints);
Expand Down
1 change: 1 addition & 0 deletions atom/browser/native_window_views.h
Expand Up @@ -67,6 +67,7 @@ class NativeWindowViews : public NativeWindow,
gfx::Rect GetBounds() override;
gfx::Rect GetContentBounds() override;
gfx::Size GetContentSize() override;
gfx::Rect GetNormalBounds() override;
void SetContentSizeConstraints(
const extensions::SizeConstraints& size_constraints) override;
void SetResizable(bool resizable) override;
Expand Down
10 changes: 10 additions & 0 deletions docs/api/browser-window.md
Expand Up @@ -807,6 +807,10 @@ Simple fullscreen mode emulates the native fullscreen behavior found in versions

Returns `Boolean` - Whether the window is in simple (pre-Lion) fullscreen mode.

#### `win.isNormal()`

Returns `Boolean` - Whether the window is in normal state (not maximized, not minimized, not in fullscreen mode).

#### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_

* `aspectRatio` Float - The aspect ratio to maintain for some portion of the
Expand Down Expand Up @@ -869,6 +873,12 @@ the supplied bounds.

Returns [`Rectangle`](structures/rectangle.md)

#### `win.getNormalBounds()`

Returns [`Rectangle`](structures/rectangle.md) - Contains the window bounds of the normal state

**Note:** whatever the current state of the window : maximized, minimized or in fullscreen, this function always returns the position and size of the window in normal state. In normal state, getBounds and getNormalBounds returns the same [`Rectangle`](structures/rectangle.md).

#### `win.setEnabled(enable)`

* `enable` Boolean
Expand Down
108 changes: 108 additions & 0 deletions spec/api-browser-window-spec.js
Expand Up @@ -550,6 +550,114 @@ describe('BrowserWindow module', () => {
})
})

describe(`BrowserWindow.getNormalBounds()`, () => {
describe(`Normal state`, () => {
it(`checks normal bounds after resize`, (done) => {
const size = [300, 400]
w.once('resize', () => {
assertBoundsEqual(w.getNormalBounds(), w.getBounds())
done()
})
w.setSize(size[0], size[1])
})
it(`checks normal bounds after move`, (done) => {
const pos = [10, 10]
w.once('move', () => {
assertBoundsEqual(w.getNormalBounds(), w.getBounds())
done()
})
w.setPosition(pos[0], pos[1])
})
})
describe(`Maximized state`, () => {
before(function () {
if (isCI) {
this.skip()
}
})
it(`checks normal bounds when maximized`, (done) => {
const bounds = w.getBounds()
w.once('maximize', () => {
assertBoundsEqual(w.getNormalBounds(), bounds)
done()
})
w.show()
w.maximize()
})
it(`checks normal bounds when unmaximized`, (done) => {
const bounds = w.getBounds()
w.once('maximize', () => {
w.unmaximize()
})
w.once('unmaximize', () => {
assertBoundsEqual(w.getNormalBounds(), bounds)
done()
})
w.show()
w.maximize()
})
})
describe(`Minimized state`, () => {
before(function () {
if (isCI) {
this.skip()
}
})
it(`checks normal bounds when minimized`, (done) => {
const bounds = w.getBounds()
w.once('minimize', () => {
assertBoundsEqual(w.getNormalBounds(), bounds)
done()
})
w.show()
w.minimize()
})
it(`checks normal bounds when restored`, (done) => {
const bounds = w.getBounds()
w.once('minimize', () => {
w.restore()
})
w.once('restore', () => {
assertBoundsEqual(w.getNormalBounds(), bounds)
done()
})
w.show()
w.minimize()
})
})
describe(`Fullscreen state`, () => {
before(function () {
if (isCI) {
this.skip()
}
if (process.platform === 'darwin') {
this.skip()
}
})
it(`checks normal bounds when fullscreen'ed`, (done) => {
const bounds = w.getBounds()
w.once('enter-full-screen', () => {
assertBoundsEqual(w.getNormalBounds(), bounds)
done()
})
w.show()
w.setFullScreen(true)
})
it(`checks normal bounds when unfullscreen'ed`, (done) => {
const bounds = w.getBounds()
w.once('enter-full-screen', () => {
w.setFullScreen(false)
})
w.once('leave-full-screen', () => {
assertBoundsEqual(w.getNormalBounds(), bounds)
done()
})
w.show()
w.setFullScreen(true)
})
})
})

describe('BrowserWindow.setProgressBar(progress)', () => {
it('sets the progress', () => {
assert.doesNotThrow(() => {
Expand Down