Skip to content

Commit

Permalink
feat: BrowserWindow.getNormalBounds() (#13290)
Browse files Browse the repository at this point in the history
* First commit

* Add Mac support (1st attempt)

* Add Mac support (2nd attempt)

* Simplify tests

* Restore window state !

* Looking at other tests, seems minimize, maximize, fullscreen are skipped when in CI

* Fix Mac tests

* Restore tests in CI

* Fix typo

* widget getRestoredBounds not working on Mac !!

* widget getRestoredBounds not working on Mac !!

* Add IsNormal function

* Add IsNormal

* IsNormal => isNormal

* Deactivate fullscreen on Mac. Do not receive leave-fullscreen event

* Set default original_frame_

* Set default original_frame_

* Fix Mac
  • Loading branch information
Emmanuel Kimmerlin authored and MarshallOfSound committed Aug 24, 2018
1 parent 872890e commit 5f6706a
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 1 deletion.
10 changes: 10 additions & 0 deletions atom/browser/api/atom_api_top_level_window.cc
Expand Up @@ -365,6 +365,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 @@ -967,6 +975,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 @@ -110,6 +110,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 @@ -816,6 +816,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 @@ -878,6 +882,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 @@ -558,6 +558,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

0 comments on commit 5f6706a

Please sign in to comment.