diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index c225dd717c63..627b6e92d4c8 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/atom/browser/api/atom_api_window.cc @@ -603,6 +603,14 @@ void Window::SetSkipTaskbar(bool skip) { window_->SetSkipTaskbar(skip); } +void Window::SetSimpleFullScreen(bool simple_fullscreen) { + window_->SetSimpleFullScreen(simple_fullscreen); +} + +bool Window::IsSimpleFullScreen() { + return window_->IsSimpleFullScreen(); +} + void Window::SetKiosk(bool kiosk) { window_->SetKiosk(kiosk); } @@ -1041,6 +1049,8 @@ void Window::BuildPrototype(v8::Isolate* isolate, .SetMethod("getTitle", &Window::GetTitle) .SetMethod("flashFrame", &Window::FlashFrame) .SetMethod("setSkipTaskbar", &Window::SetSkipTaskbar) + .SetMethod("setSimpleFullScreen", &Window::SetSimpleFullScreen) + .SetMethod("isSimpleFullScreen", &Window::IsSimpleFullScreen) .SetMethod("setKiosk", &Window::SetKiosk) .SetMethod("isKiosk", &Window::IsKiosk) .SetMethod("setBackgroundColor", &Window::SetBackgroundColor) diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 5dc5cfa6b577..04956a4861c4 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -154,6 +154,8 @@ class Window : public mate::TrackableObject, std::string GetTitle(); void FlashFrame(bool flash); void SetSkipTaskbar(bool skip); + void SetSimpleFullScreen(bool simple_fullscreen); + bool IsSimpleFullScreen(); void SetKiosk(bool kiosk); bool IsKiosk(); void SetBackgroundColor(const std::string& color_name); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 1ec9417e173e..b2992ec39e7f 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -134,6 +134,8 @@ class NativeWindow : public base::SupportsUserData, virtual std::string GetTitle() = 0; virtual void FlashFrame(bool flash) = 0; virtual void SetSkipTaskbar(bool skip) = 0; + virtual void SetSimpleFullScreen(bool simple_fullscreen) = 0; + virtual bool IsSimpleFullScreen() = 0; virtual void SetKiosk(bool kiosk) = 0; virtual bool IsKiosk() = 0; virtual void SetBackgroundColor(const std::string& color_name) = 0; diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 76f1e8292873..a88df1111329 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -76,6 +76,8 @@ class NativeWindowMac : public NativeWindow, std::string GetTitle() override; void FlashFrame(bool flash) override; void SetSkipTaskbar(bool skip) override; + void SetSimpleFullScreen(bool simple_fullscreen) override; + bool IsSimpleFullScreen() override; void SetKiosk(bool kiosk) override; bool IsKiosk() override; void SetBackgroundColor(const std::string& color_name) override; @@ -141,6 +143,8 @@ class NativeWindowMac : public NativeWindow, bool fullscreen_window_title() const { return fullscreen_window_title_; } + bool simple_fullscreen() const { return always_simple_fullscreen_; } + 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. @@ -195,6 +199,17 @@ class NativeWindowMac : public NativeWindow, // The "titleBarStyle" option. TitleBarStyle title_bar_style_; + // Simple (pre-Lion) Fullscreen Settings + bool always_simple_fullscreen_; + bool is_simple_fullscreen_; + bool was_maximizable_; + bool was_movable_; + NSRect original_frame_; + NSUInteger simple_fullscreen_mask_; + + // The presentation options before entering simple fullscreen mode. + NSApplicationPresentationOptions simple_fullscreen_options_; + DISALLOW_COPY_AND_ASSIGN(NativeWindowMac); }; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 9d8464295a3b..cc77087efd4f 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -730,6 +730,13 @@ enum { [super performClose:sender]; } +- (void)toggleFullScreen:(id)sender { + if (shell_->simple_fullscreen()) + shell_->SetSimpleFullScreen(!shell_->IsSimpleFullScreen()); + else + [super toggleFullScreen:sender]; +} + - (void)performMiniaturize:(id)sender { if (shell_->title_bar_style() == atom::NativeWindowMac::CUSTOM_BUTTONS_ON_HOVER) [self miniaturize:self]; @@ -829,7 +836,9 @@ NativeWindowMac::NativeWindowMac( zoom_to_page_width_(false), fullscreen_window_title_(false), attention_request_id_(0), - title_bar_style_(NORMAL) { + title_bar_style_(NORMAL), + always_simple_fullscreen_(false), + is_simple_fullscreen_(false) { int width = 800, height = 600; options.Get(options::kWidth, &width); options.Get(options::kHeight, &height); @@ -975,6 +984,8 @@ NativeWindowMac::NativeWindowMac( options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_); + options.Get(options::kSimpleFullScreen, &always_simple_fullscreen_); + // Enable the NSView to accept first mouse event. bool acceptsFirstMouse = false; options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse); @@ -1361,6 +1372,80 @@ void NativeWindowMac::FlashFrame(bool flash) { void NativeWindowMac::SetSkipTaskbar(bool skip) { } +void NativeWindowMac::SetSimpleFullScreen(bool simple_fullscreen) { + NSWindow* window = GetNativeWindow(); + + if (simple_fullscreen && !is_simple_fullscreen_) { + is_simple_fullscreen_ = true; + + // Take note of the current window size + original_frame_ = [window frame]; + + simple_fullscreen_options_ = [NSApp currentSystemPresentationOptions]; + simple_fullscreen_mask_ = [window styleMask]; + + // We can simulate the pre-Lion fullscreen by auto-hiding the dock and menu bar + NSApplicationPresentationOptions options = + NSApplicationPresentationAutoHideDock + + NSApplicationPresentationAutoHideMenuBar; + [NSApp setPresentationOptions:options]; + + was_maximizable_ = IsMaximizable(); + was_movable_ = IsMovable(); + + NSRect fullscreenFrame = [window.screen frame]; + + if ( !fullscreen_window_title() ) { + // Hide the titlebar + SetStyleMask(false, NSTitledWindowMask); + + // Resize the window to accomodate the _entire_ screen size + fullscreenFrame.size.height -= [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; + } else { + // No need to hide the title, but we should still hide the window buttons + [[window standardWindowButton:NSWindowZoomButton] setHidden:YES]; + [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; + [[window standardWindowButton:NSWindowCloseButton] setHidden:YES]; + } + + [window setFrame:fullscreenFrame display: YES animate: YES]; + + // Fullscreen windows can't be resized, minimized, maximized, or moved + SetMinimizable(false); + SetResizable(false); + SetMaximizable(false); + SetMovable(false); + } else if (!simple_fullscreen && is_simple_fullscreen_) { + is_simple_fullscreen_ = false; + + if ( !fullscreen_window_title() ) { + // Restore the titlebar + SetStyleMask(true, NSTitledWindowMask); + } else { + // Show the window buttons + [[window standardWindowButton:NSWindowZoomButton] setHidden:NO]; + [[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:NO]; + [[window standardWindowButton:NSWindowCloseButton] setHidden:NO]; + } + + [window setFrame:original_frame_ display: YES animate: YES]; + + [NSApp setPresentationOptions:simple_fullscreen_options_]; + + // Restore original style mask + ScopedDisableResize disable_resize; + [window_ setStyleMask:simple_fullscreen_mask_]; + + // Restore window manipulation abilities + SetMaximizable(was_maximizable_); + SetMovable(was_movable_); + } +} + +bool NativeWindowMac::IsSimpleFullScreen() { + return is_simple_fullscreen_; +} + void NativeWindowMac::SetKiosk(bool kiosk) { if (kiosk && !is_kiosk_) { kiosk_options_ = [NSApp currentSystemPresentationOptions]; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 11c2436d7834..3b633ab96355 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -770,6 +770,14 @@ void NativeWindowViews::SetSkipTaskbar(bool skip) { #endif } +void NativeWindowViews::SetSimpleFullScreen(bool simple_fullscreen) { + SetFullScreen(simple_fullscreen); +} + +bool NativeWindowViews::IsSimpleFullScreen() { + return IsFullscreen(); +} + void NativeWindowViews::SetKiosk(bool kiosk) { SetFullScreen(kiosk); } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index fe493918117d..34ba2c8663ee 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -97,6 +97,8 @@ class NativeWindowViews : public NativeWindow, std::string GetTitle() override; void FlashFrame(bool flash) override; void SetSkipTaskbar(bool skip) override; + void SetSimpleFullScreen(bool simple_fullscreen) override; + bool IsSimpleFullScreen() override; void SetKiosk(bool kiosk) override; bool IsKiosk() override; void SetBackgroundColor(const std::string& color_name) override; diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 8822c55f9a4f..76aa1903f790 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -36,6 +36,8 @@ const char kSkipTaskbar[] = "skipTaskbar"; // http://www.opera.com/support/mastering/kiosk/ const char kKiosk[] = "kiosk"; +const char kSimpleFullScreen[] = "simpleFullscreen"; + // Make windows stays on the top of all other windows. const char kAlwaysOnTop[] = "alwaysOnTop"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 171e6b5a79fb..fde740cd9190 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -31,6 +31,7 @@ extern const char kClosable[]; extern const char kFullscreen[]; extern const char kSkipTaskbar[]; extern const char kKiosk[]; +extern const char kSimpleFullScreen[]; extern const char kAlwaysOnTop[]; extern const char kAcceptFirstMouse[]; extern const char kUseContentSize[]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index b01e5dc78078..4d6e921eb185 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -176,6 +176,7 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. * `fullscreenable` Boolean (optional) - Whether the window can be put into fullscreen mode. On macOS, also whether the maximize/zoom button should toggle full screen mode or maximize window. Default is `true`. + * `simpleFullscreen` Boolean (optional) - Use pre-Lion fullscreen on macOS. Default is `false`. * `skipTaskbar` Boolean (optional) - Whether to show the window in taskbar. Default is `false`. * `kiosk` Boolean (optional) - The kiosk mode. Default is `false`. @@ -767,6 +768,18 @@ Sets whether the window should be in fullscreen mode. Returns `Boolean` - Whether the window is in fullscreen mode. +#### `win.setSimpleFullScreen(flag)` _macOS_ + +* `flag` Boolean + +Enters or leaves simple fullscreen mode. + +Simple fullscreen mode emulates the native fullscreen behavior found in versions of Mac OS X prior to Lion (10.7). + +#### `win.isSimpleFullScreen()` _macOS_ + +Returns `Boolean` - Whether the window is in simple (pre-Lion) fullscreen mode. + #### `win.setAspectRatio(aspectRatio[, extraSize])` _macOS_ * `aspectRatio` Float - The aspect ratio to maintain for some portion of the