From c5790e39dc4c83b03b10b3b3b8758e7f0428015b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 26 Oct 2016 12:12:12 +0900 Subject: [PATCH 1/8] Add support for zooming to content size --- atom/browser/native_window_mac.h | 4 +++ atom/browser/native_window_mac.mm | 49 +++++++++++++++++++++++++++++++ atom/common/options_switches.cc | 3 ++ atom/common/options_switches.h | 1 + 4 files changed, 57 insertions(+) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 339e10e853c7..6bd2c69ed4d5 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -117,6 +117,8 @@ class NativeWindowMac : public NativeWindow, }; TitleBarStyle title_bar_style() const { return title_bar_style_; } + bool zoom_to_content_size() const { return zoom_to_content_size_; } + protected: // Return a vector of non-draggable regions that fill a window of size // |width| by |height|, but leave gaps where the window should be draggable. @@ -155,6 +157,8 @@ class NativeWindowMac : public NativeWindow, bool is_kiosk_; + bool zoom_to_content_size_; + NSInteger attention_request_id_; // identifier from requestUserAttention // The presentation options before entering kiosk mode. diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 42157f93f9d8..69dd29b4f0b5 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -102,6 +102,52 @@ bool ScopedDisableResize::disable_resize_ = false; } } +// Called when the user clicks the zoom button or selects it from the Window +// menu) to determine the "standard size" of the window. +- (NSRect)windowWillUseStandardFrame:(NSWindow*)window + defaultFrame:(NSRect)frame { + if (!shell_->zoom_to_content_size()) + return frame; + + // If the shift key is down, maximize. + if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) + return frame; + + // To prevent strange results on portrait displays, the basic minimum zoomed + // width is the larger of: 60% of available width, 60% of available height + // (bounded by available width). + const CGFloat kProportion = 0.6; + CGFloat zoomedWidth = + std::max(kProportion * NSWidth(frame), + std::min(kProportion * NSHeight(frame), NSWidth(frame))); + + content::WebContents* web_contents = shell_->web_contents(); + if (web_contents) { + // If the intrinsic width is bigger, then make it the zoomed width. + const int kScrollbarWidth = 16; // TODO(viettrungluu): ugh. + CGFloat intrinsicWidth = static_cast( + web_contents->GetPreferredSize().width() + kScrollbarWidth); + zoomedWidth = std::max(zoomedWidth, + std::min(intrinsicWidth, NSWidth(frame))); + } + + // Never shrink from the current size on zoom (see above). + NSRect currentFrame = [shell_->GetNativeWindow() frame]; + zoomedWidth = std::max(zoomedWidth, NSWidth(currentFrame)); + + // |frame| determines our maximum extents. We need to set the origin of the + // frame -- and only move it left if necessary. + if (currentFrame.origin.x + zoomedWidth > NSMaxX(frame)) + frame.origin.x = NSMaxX(frame) - zoomedWidth; + else + frame.origin.x = currentFrame.origin.x; + + // Set the width. Don't touch y or height. + frame.size.width = zoomedWidth; + + return frame; +} + - (void)windowDidBecomeMain:(NSNotification*)notification { content::WebContents* web_contents = shell_->web_contents(); if (!web_contents) @@ -584,6 +630,7 @@ NativeWindowMac::NativeWindowMac( NativeWindow* parent) : NativeWindow(web_contents, options, parent), is_kiosk_(false), + zoom_to_content_size_(false), attention_request_id_(0), title_bar_style_(NORMAL) { int width = 800, height = 600; @@ -706,6 +753,8 @@ NativeWindowMac::NativeWindowMac( if (!has_frame() || !use_content_size) SetSize(gfx::Size(width, height)); + options.Get(options::kZoomToContentSize, &zoom_to_content_size_); + // Enable the NSView to accept first mouse event. bool acceptsFirstMouse = false; options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse); diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 00b2c8c02688..eab2cf8145e5 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -45,6 +45,9 @@ const char kAcceptFirstMouse[] = "acceptFirstMouse"; // Whether window size should include window frame. const char kUseContentSize[] = "useContentSize"; +// Whether window zoom should be to content size. +const char kZoomToContentSize[] = "zoomToContentSize"; + // The requested title bar style for the window const char kTitleBarStyle[] = "titleBarStyle"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 345329524b71..fcd98550b0a6 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -34,6 +34,7 @@ extern const char kKiosk[]; extern const char kAlwaysOnTop[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; +extern const char kZoomToContentSize[]; extern const char kTitleBarStyle[]; extern const char kAutoHideMenuBar[]; extern const char kEnableLargerThanScreen[]; From 7896ee23a2296c8aa2d0e20e30ef6b7ae3bc7e13 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 27 Oct 2016 11:17:24 -0700 Subject: [PATCH 2/8] Document zoomToContentSize --- docs/api/browser-window.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 5ff2380a5813..32f991f36b87 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -205,6 +205,12 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `vibrancy` String - Add a type of vibrancy effect to the window, only on macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light` or `ultra-dark`. + * `zoomToContentSize` Boolean - The zoom behavior on macOS, accessible by + option-clicking the green stoplight button on the toolbar or running the + Window > Zoom menu item. If `true`, the window will grow to the width of the + web page, `false` will cause it to zoom to the width of the screen. This + will also affect the behavior when calling `maximize()` directly. Default is + `false`. * `webPreferences` Object (optional) - Settings of web page's features. * `devTools` Boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`. * `nodeIntegration` Boolean (optional) - Whether node integration is enabled. Default From 7916981da2666ceb4bc4100e88e3ae958dd7e8c8 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 27 Oct 2016 11:29:51 -0700 Subject: [PATCH 3/8] zoomToContentSize -> zoomToPageWidth --- atom/browser/native_window_mac.h | 4 ++-- atom/browser/native_window_mac.mm | 6 +++--- atom/common/options_switches.cc | 4 ++-- atom/common/options_switches.h | 2 +- docs/api/browser-window.md | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 6bd2c69ed4d5..7c4d2b4eef2f 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -117,7 +117,7 @@ class NativeWindowMac : public NativeWindow, }; TitleBarStyle title_bar_style() const { return title_bar_style_; } - bool zoom_to_content_size() const { return zoom_to_content_size_; } + bool zoom_to_page_width() const { return zoom_to_page_width_; } protected: // Return a vector of non-draggable regions that fill a window of size @@ -157,7 +157,7 @@ class NativeWindowMac : public NativeWindow, bool is_kiosk_; - bool zoom_to_content_size_; + bool zoom_to_page_width_; NSInteger attention_request_id_; // identifier from requestUserAttention diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 69dd29b4f0b5..23cb80b183f6 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -106,7 +106,7 @@ bool ScopedDisableResize::disable_resize_ = false; // menu) to determine the "standard size" of the window. - (NSRect)windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)frame { - if (!shell_->zoom_to_content_size()) + if (!shell_->zoom_to_page_width()) return frame; // If the shift key is down, maximize. @@ -630,7 +630,7 @@ NativeWindowMac::NativeWindowMac( NativeWindow* parent) : NativeWindow(web_contents, options, parent), is_kiosk_(false), - zoom_to_content_size_(false), + zoom_to_page_width_(false), attention_request_id_(0), title_bar_style_(NORMAL) { int width = 800, height = 600; @@ -753,7 +753,7 @@ NativeWindowMac::NativeWindowMac( if (!has_frame() || !use_content_size) SetSize(gfx::Size(width, height)); - options.Get(options::kZoomToContentSize, &zoom_to_content_size_); + options.Get(options::kZoomToPageWidth, &zoom_to_page_width_); // Enable the NSView to accept first mouse event. bool acceptsFirstMouse = false; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index eab2cf8145e5..70aeccfc9bc7 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -45,8 +45,8 @@ const char kAcceptFirstMouse[] = "acceptFirstMouse"; // Whether window size should include window frame. const char kUseContentSize[] = "useContentSize"; -// Whether window zoom should be to content size. -const char kZoomToContentSize[] = "zoomToContentSize"; +// Whether window zoom should be to page width. +const char kZoomToPageWidth[] = "zoomToPageWidth"; // The requested title bar style for the window const char kTitleBarStyle[] = "titleBarStyle"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index fcd98550b0a6..3c9abebf4ce4 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -34,7 +34,7 @@ extern const char kKiosk[]; extern const char kAlwaysOnTop[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; -extern const char kZoomToContentSize[]; +extern const char kZoomToPageWidth[]; extern const char kTitleBarStyle[]; extern const char kAutoHideMenuBar[]; extern const char kEnableLargerThanScreen[]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 32f991f36b87..5305d1ffafce 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -205,7 +205,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `vibrancy` String - Add a type of vibrancy effect to the window, only on macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light` or `ultra-dark`. - * `zoomToContentSize` Boolean - The zoom behavior on macOS, accessible by + * `zoomToPageWidth` Boolean - The zoom behavior on macOS, accessible by option-clicking the green stoplight button on the toolbar or running the Window > Zoom menu item. If `true`, the window will grow to the width of the web page, `false` will cause it to zoom to the width of the screen. This From b02c0e6f46076ad09cfd28fdd0bdd83aaf46e077 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 27 Oct 2016 11:49:13 -0700 Subject: [PATCH 4/8] Remove unneeded proportion calculation --- atom/browser/native_window_mac.mm | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 23cb80b183f6..d0ea0b72c7e5 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -103,7 +103,7 @@ bool ScopedDisableResize::disable_resize_ = false; } // Called when the user clicks the zoom button or selects it from the Window -// menu) to determine the "standard size" of the window. +// menu to determine the "standard size" of the window. - (NSRect)windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)frame { if (!shell_->zoom_to_page_width()) @@ -113,27 +113,17 @@ bool ScopedDisableResize::disable_resize_ = false; if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) return frame; - // To prevent strange results on portrait displays, the basic minimum zoomed - // width is the larger of: 60% of available width, 60% of available height - // (bounded by available width). - const CGFloat kProportion = 0.6; - CGFloat zoomedWidth = - std::max(kProportion * NSWidth(frame), - std::min(kProportion * NSHeight(frame), NSWidth(frame))); - content::WebContents* web_contents = shell_->web_contents(); - if (web_contents) { - // If the intrinsic width is bigger, then make it the zoomed width. - const int kScrollbarWidth = 16; // TODO(viettrungluu): ugh. - CGFloat intrinsicWidth = static_cast( - web_contents->GetPreferredSize().width() + kScrollbarWidth); - zoomedWidth = std::max(zoomedWidth, - std::min(intrinsicWidth, NSWidth(frame))); - } + if (!web_contents) + return frame; - // Never shrink from the current size on zoom (see above). - NSRect currentFrame = [shell_->GetNativeWindow() frame]; - zoomedWidth = std::max(zoomedWidth, NSWidth(currentFrame)); + CGFloat intrinsicWidth = static_cast( + web_contents->GetPreferredSize().width()); + + NSRect currentFrame = [window frame]; + + // Never shrink from the current size on zoom. + CGFloat zoomedWidth = std::max(intrinsicWidth, NSWidth(currentFrame)); // |frame| determines our maximum extents. We need to set the origin of the // frame -- and only move it left if necessary. From d4ba5b46383f56af7f412292b03de558e3e7c386 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 27 Oct 2016 11:54:27 -0700 Subject: [PATCH 5/8] Add spec for zoomToPageWidth --- spec/api-browser-window-spec.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index cdfdb384421d..a0425d7ffc63 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -626,6 +626,22 @@ describe('browser-window module', function () { }) }) + describe('"zoomToPageWidth" option', function () { + it('sets the window width to the page width when used', function () { + if (process.platform !== 'darwin') return this.skip() + + w.destroy() + w = new BrowserWindow({ + show: false, + width: 500, + height: 400, + zoomToPageWidth: true + }) + w.maximize() + assert.equal(w.getSize()[0], 500) + }) + }) + describe('"web-preferences" option', function () { afterEach(function () { ipcMain.removeAllListeners('answer') From a991570677c75ecec727ffdaad1c2b7710133aa2 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 27 Oct 2016 11:56:41 -0700 Subject: [PATCH 6/8] intrinsicWidth -> pageWidth --- atom/browser/native_window_mac.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index d0ea0b72c7e5..fcf4bd5e7350 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -117,13 +117,12 @@ bool ScopedDisableResize::disable_resize_ = false; if (!web_contents) return frame; - CGFloat intrinsicWidth = static_cast( + CGFloat pageWidth = static_cast( web_contents->GetPreferredSize().width()); - NSRect currentFrame = [window frame]; // Never shrink from the current size on zoom. - CGFloat zoomedWidth = std::max(intrinsicWidth, NSWidth(currentFrame)); + CGFloat zoomedWidth = std::max(pageWidth, NSWidth(currentFrame)); // |frame| determines our maximum extents. We need to set the origin of the // frame -- and only move it left if necessary. From 2fc46f638fbc341aeaebe8ce716eb3fb6fae512b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 27 Oct 2016 12:13:45 -0700 Subject: [PATCH 7/8] :art: --- atom/browser/native_window_mac.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index fcf4bd5e7350..5ba0700a1863 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -117,22 +117,22 @@ bool ScopedDisableResize::disable_resize_ = false; if (!web_contents) return frame; - CGFloat pageWidth = static_cast( + CGFloat page_width = static_cast( web_contents->GetPreferredSize().width()); - NSRect currentFrame = [window frame]; + NSRect window_frame = [window frame]; // Never shrink from the current size on zoom. - CGFloat zoomedWidth = std::max(pageWidth, NSWidth(currentFrame)); + CGFloat zoomed_width = std::max(page_width, NSWidth(window_frame)); // |frame| determines our maximum extents. We need to set the origin of the // frame -- and only move it left if necessary. - if (currentFrame.origin.x + zoomedWidth > NSMaxX(frame)) - frame.origin.x = NSMaxX(frame) - zoomedWidth; + if (window_frame.origin.x + zoomed_width > NSMaxX(frame)) + frame.origin.x = NSMaxX(frame) - zoomed_width; else - frame.origin.x = currentFrame.origin.x; + frame.origin.x = window_frame.origin.x; // Set the width. Don't touch y or height. - frame.size.width = zoomedWidth; + frame.size.width = zoomed_width; return frame; } From ea6b53578f3e4e537e14a80f20bf18bfdcb4d28c Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 17 Nov 2016 13:12:52 -0800 Subject: [PATCH 8/8] Mention preferred size --- docs/api/browser-window.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 5305d1ffafce..40a2ccacac38 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -205,12 +205,12 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `vibrancy` String - Add a type of vibrancy effect to the window, only on macOS. Can be `appearance-based`, `light`, `dark`, `titlebar`, `selection`, `menu`, `popover`, `sidebar`, `medium-light` or `ultra-dark`. - * `zoomToPageWidth` Boolean - The zoom behavior on macOS, accessible by - option-clicking the green stoplight button on the toolbar or running the - Window > Zoom menu item. If `true`, the window will grow to the width of the - web page, `false` will cause it to zoom to the width of the screen. This - will also affect the behavior when calling `maximize()` directly. Default is - `false`. + * `zoomToPageWidth` Boolean - Controls the behavior on macOS when + option-clicking the green stoplight button on the toolbar or by clicking the + Window > Zoom menu item. If `true`, the window will grow to the preferred + width of the web page when zoomed, `false` will cause it to zoom to the + width of the screen. This will also affect the behavior when calling + `maximize()` directly. Default is `false`. * `webPreferences` Object (optional) - Settings of web page's features. * `devTools` Boolean (optional) - Whether to enable DevTools. If it is set to `false`, can not use `BrowserWindow.webContents.openDevTools()` to open DevTools. Default is `true`. * `nodeIntegration` Boolean (optional) - Whether node integration is enabled. Default