Browse Source

Add support for simple (pre-Lion) fullscreen on Mac OS

Zachary Flower 7 years ago
parent
commit
ba5fa2c8b1

+ 10 - 0
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);
 }
@@ -1018,6 +1026,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)

+ 2 - 0
atom/browser/api/atom_api_window.h

@@ -154,6 +154,8 @@ class Window : public mate::TrackableObject<Window>,
   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);

+ 2 - 0
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;

+ 17 - 0
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;
@@ -135,6 +137,8 @@ class NativeWindowMac : public NativeWindow,
 
   bool fullscreen_window_title() const { return fullscreen_window_title_; }
 
+  bool simple_fullscreen() const { return 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.
@@ -189,6 +193,19 @@ class NativeWindowMac : public NativeWindow,
   // The "titleBarStyle" option.
   TitleBarStyle title_bar_style_;
 
+  // Simple (pre-Lion) Fullscreen Settings
+  bool simple_fullscreen_;
+  bool is_simple_fullscreen_;
+  bool was_maximized_;
+  bool was_minimizable_;
+  bool was_maximizable_;
+  bool was_resizable_;
+  bool was_movable_;
+  NSRect original_frame_;
+
+  // The presentation options before entering simple fullscreen mode.
+  NSApplicationPresentationOptions simple_fullscreen_options_;
+
   DISALLOW_COPY_AND_ASSIGN(NativeWindowMac);
 };
 

+ 89 - 1
atom/browser/native_window_mac.mm

@@ -720,6 +720,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];
@@ -819,7 +826,9 @@ NativeWindowMac::NativeWindowMac(
       zoom_to_page_width_(false),
       fullscreen_window_title_(false),
       attention_request_id_(0),
-      title_bar_style_(NORMAL) {
+      title_bar_style_(NORMAL),
+      simple_fullscreen_(false),
+      is_simple_fullscreen_(false) {
   int width = 800, height = 600;
   options.Get(options::kWidth, &width);
   options.Get(options::kHeight, &height);
@@ -965,6 +974,8 @@ NativeWindowMac::NativeWindowMac(
 
   options.Get(options::kFullscreenWindowTitle, &fullscreen_window_title_);
 
+  options.Get(options::kSimpleFullScreen, &simple_fullscreen_);
+
   // Enable the NSView to accept first mouse event.
   bool acceptsFirstMouse = false;
   options.Get(options::kAcceptFirstMouse, &acceptsFirstMouse);
@@ -1351,6 +1362,83 @@ 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];
+
+    // We can simulate the pre-Lion fullscreen by auto-hiding the dock and menu bar
+    NSApplicationPresentationOptions options =
+        NSApplicationPresentationAutoHideDock +
+        NSApplicationPresentationAutoHideMenuBar;
+    [NSApp setPresentationOptions:options];
+
+    was_maximized_ = IsMaximized();
+    was_minimizable_ = IsMinimizable();
+    was_maximizable_ = IsMaximizable();
+    was_resizable_ = IsResizable();
+    was_movable_ = IsMovable();
+
+    // if (!was_maximized_) Maximize();
+
+    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, etc.
+    if (was_minimizable_) SetMinimizable(false);
+    if (was_maximizable_) SetMaximizable(false);
+    if (was_resizable_) SetResizable(false);
+    if (was_movable_) 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 window manipulation abilities
+    // if (!was_maximized_) Unmaximize();
+    if (was_minimizable_) SetMinimizable(true);
+    if (was_maximizable_) SetMaximizable(true);
+    if (was_resizable_) SetResizable(true);
+    if (was_movable_) SetMovable(true);
+  }
+}
+
+bool NativeWindowMac::IsSimpleFullScreen() {
+  return is_simple_fullscreen_;
+}
+
 void NativeWindowMac::SetKiosk(bool kiosk) {
   if (kiosk && !is_kiosk_) {
     kiosk_options_ = [NSApp currentSystemPresentationOptions];

+ 8 - 0
atom/browser/native_window_views.cc

@@ -754,6 +754,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);
 }

+ 2 - 0
atom/browser/native_window_views.h

@@ -96,6 +96,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;

+ 2 - 0
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";
 

+ 1 - 0
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[];