diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index d5bce5891135..ae907b0669d5 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -249,6 +249,10 @@ bool Window::IsFullscreen() { return window_->IsFullscreen(); } +void Window::MaintainAspectRatioOfInteriorContent(double aspectRatio, double extraWidth, double extraHeight) { + window_->MaintainAspectRatioOfInteriorContent(aspectRatio, gfx::Size(extraWidth, extraHeight)); +} + void Window::SetBounds(const gfx::Rect& bounds) { window_->SetBounds(bounds); } @@ -498,6 +502,7 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("isMinimized", &Window::IsMinimized) .SetMethod("setFullScreen", &Window::SetFullScreen) .SetMethod("isFullScreen", &Window::IsFullscreen) + .SetMethod("maintainAspectRatioOfInteriorContent", &Window::MaintainAspectRatioOfInteriorContent) .SetMethod("getBounds", &Window::GetBounds) .SetMethod("setBounds", &Window::SetBounds) .SetMethod("getSize", &Window::GetSize) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 5cdb49e41bbf..8c27f5b36a6f 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -95,6 +95,7 @@ class Window : public mate::TrackableObject, bool IsMinimized(); void SetFullScreen(bool fullscreen); bool IsFullscreen(); + void MaintainAspectRatioOfInteriorContent(double aspectRatio, double extraWidth, double extraHeight); void SetBounds(const gfx::Rect& bounds); gfx::Rect GetBounds(); void SetSize(int width, int height); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 2a093cc81200..8e21876fdfa3 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -195,6 +195,19 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) { Show(); } +double NativeWindow::GetInteriorContentAspectRatio() { + return interiorContentAspectRatio; +} + +gfx::Size NativeWindow::GetInteriorContentExtraSize() { + return interiorContentExtraSize; +} + +void NativeWindow::MaintainAspectRatioOfInteriorContent(double aspectRatio, const gfx::Size& extraSize) { + interiorContentAspectRatio = aspectRatio; + interiorContentExtraSize = extraSize; +} + void NativeWindow::SetSize(const gfx::Size& size) { SetBounds(gfx::Rect(GetPosition(), size)); } diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 0ac7aa50c915..e9e159a7ea3b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -107,6 +107,9 @@ class NativeWindow : public content::WebContentsObserver, virtual bool IsMinimized() = 0; virtual void SetFullScreen(bool fullscreen) = 0; virtual bool IsFullscreen() const = 0; + double GetInteriorContentAspectRatio(); + virtual gfx::Size GetInteriorContentExtraSize(); + virtual void MaintainAspectRatioOfInteriorContent(double aspectRatio, const gfx::Size& extraSize); virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual gfx::Rect GetBounds() = 0; virtual void SetSize(const gfx::Size& size); @@ -285,6 +288,10 @@ class NativeWindow : public content::WebContentsObserver, // Page's default zoom factor. double zoom_factor_; + // Used to maintain the aspect ratio of a view which is inside of the content view. + double interiorContentAspectRatio = 0.0; + gfx::Size interiorContentExtraSize; + // The page this window is viewing. brightray::InspectableWebContents* inspectable_web_contents_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index c0d358bb8f72..de7e8ad77967 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -95,6 +95,33 @@ static const CGFloat kAtomWindowCornerRadius = 4.0; shell_->NotifyWindowBlur(); } +- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize { + NSSize newSize = frameSize; + double interiorContentAspectRatio = shell_->GetInteriorContentAspectRatio(); + + if (interiorContentAspectRatio > 0.0) { + NSRect windowFrame = [sender frame]; + NSRect contentViewBounds = [[sender contentView] bounds]; + gfx::Size interiorContentExtraSize = shell_->GetInteriorContentExtraSize(); + double extraWidthPlusFrame = windowFrame.size.width - contentViewBounds.size.width + interiorContentExtraSize.width(); + double extraHeightPlusFrame = windowFrame.size.height - contentViewBounds.size.height + interiorContentExtraSize.height(); + + newSize.width = roundf(((frameSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); + + // If the new width is less than the frame size use it as the primary constraint. This ensures that the value returned + // by this method will never be larger than the users requested window size. + if (newSize.width < frameSize.width) { + newSize.height = roundf(((newSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); + } + else { + newSize.width = roundf(((newSize.height - extraHeightPlusFrame) * interiorContentAspectRatio) + extraWidthPlusFrame); + newSize.height = roundf(((frameSize.width - extraWidthPlusFrame) / interiorContentAspectRatio) + extraHeightPlusFrame); + } + } + + return newSize; +} + - (void)windowDidResize:(NSNotification*)notification { if (!shell_->has_frame()) shell_->ClipWebView();