Browse Source

Add "New Tab" button for Native macOS Tabs

Adds responders for `newWindowForTab` to `AtomApplicationDelegate` and
`NativeWindowMac`, so that `BrowserWindow`s with a `tabbingIdentifier`
will get the new tab button, and both `app` and `window` will emit a
`new-tab-for-window` event.
Daniel Ma 7 years ago
parent
commit
4fb9f825b1

+ 5 - 0
atom/browser/api/atom_api_app.cc

@@ -585,6 +585,11 @@ void App::OnContinueUserActivity(
     const base::DictionaryValue& user_info) {
   *prevent_default = Emit("continue-activity", type, user_info);
 }
+
+void App::OnNewWindowForTab() {
+  Emit("new-window-for-tab");
+}
+
 #endif
 
 void App::OnLogin(LoginHandler* login_handler,

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

@@ -117,6 +117,8 @@ class App : public AtomBrowserClient::Delegate,
       bool* prevent_default,
       const std::string& type,
       const base::DictionaryValue& user_info) override;
+
+  void OnNewWindowForTab() override;
 #endif
 
   // content::ContentBrowserClient:

+ 4 - 0
atom/browser/api/atom_api_window.cc

@@ -300,6 +300,10 @@ void Window::OnTouchBarItemResult(const std::string& item_id,
   Emit("-touch-bar-interaction", item_id, details);
 }
 
+void Window::OnNewWindowForTab() {
+  Emit("new-window-for-tab");
+}
+
 #if defined(OS_WIN)
 void Window::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
   if (IsWindowMessageHooked(message)) {

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

@@ -91,6 +91,7 @@ class Window : public mate::TrackableObject<Window>,
   void OnExecuteWindowsCommand(const std::string& command_name) override;
   void OnTouchBarItemResult(const std::string& item_id,
                             const base::DictionaryValue& details) override;
+  void OnNewWindowForTab() override;
 
   #if defined(OS_WIN)
   void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override;

+ 7 - 0
atom/browser/browser.cc

@@ -213,4 +213,11 @@ void Browser::OnWindowAllClosed() {
   }
 }
 
+#if defined(OS_MACOSX)
+void Browser::NewWindowForTab() {
+  for (BrowserObserver& observer : observers_)
+    observer.OnNewWindowForTab();
+}
+#endif
+
 }  // namespace atom

+ 5 - 0
atom/browser/browser.h

@@ -183,6 +183,11 @@ class Browser : public WindowListObserver {
   // Tell the application to open a url.
   void OpenURL(const std::string& url);
 
+#if defined(OS_MACOSX)
+  // Tell the application to create a new window for a tab.
+  void NewWindowForTab();
+#endif  // defined(OS_MACOSX)
+
   // Tell the application that application is activated with visible/invisible
   // windows.
   void Activate(bool has_visible_windows);

+ 3 - 0
atom/browser/browser_observer.h

@@ -61,6 +61,9 @@ class BrowserObserver {
       bool* prevent_default,
       const std::string& type,
       const base::DictionaryValue& user_info) {}
+
+  // User clicked the native macOS new tab button. (macOS only)
+  virtual void OnNewWindowForTab() {}
 #endif
 
  protected:

+ 4 - 0
atom/browser/mac/atom_application_delegate.mm

@@ -81,4 +81,8 @@ continueUserActivity:(NSUserActivity*)userActivity
   return browser->ContinueUserActivity(activity_type, *user_info) ? YES : NO;
 }
 
+- (IBAction)newWindowForTab:(id)sender {
+  atom::Browser::Get()->NewWindowForTab();
+}
+
 @end

+ 5 - 0
atom/browser/native_window.cc

@@ -597,6 +597,11 @@ void NativeWindow::NotifyTouchBarItemInteraction(
     observer.OnTouchBarItemResult(item_id, details);
 }
 
+void NativeWindow::NotifyNewWindowForTab() {
+  for (NativeWindowObserver &observer : observers_)
+    observer.OnNewWindowForTab();
+}
+
 #if defined(OS_WIN)
 void NativeWindow::NotifyWindowMessage(
     UINT message, WPARAM w_param, LPARAM l_param) {

+ 1 - 0
atom/browser/native_window.h

@@ -252,6 +252,7 @@ class NativeWindow : public base::SupportsUserData,
   void NotifyWindowExecuteWindowsCommand(const std::string& command);
   void NotifyTouchBarItemInteraction(const std::string& item_id,
                                      const base::DictionaryValue& details);
+  void NotifyNewWindowForTab();
 
   #if defined(OS_WIN)
   void NotifyWindowMessage(UINT message, WPARAM w_param, LPARAM l_param);

+ 6 - 0
atom/browser/native_window_mac.mm

@@ -7,6 +7,7 @@
 #include <Quartz/Quartz.h>
 #include <string>
 
+#include "atom/browser/browser.h"
 #include "atom/browser/native_browser_view_mac.h"
 #include "atom/browser/ui/cocoa/atom_touch_bar.h"
 #include "atom/browser/window_list.h"
@@ -417,6 +418,11 @@ bool ScopedDisableResize::disable_resize_ = false;
   shell_->NotifyWindowSheetEnd();
 }
 
+- (IBAction)newWindowForTab:(id)sender {
+  shell_->NotifyNewWindowForTab();
+  atom::Browser::Get()->NewWindowForTab();
+}
+
 @end
 
 @interface AtomPreviewItem : NSObject <QLPreviewItem>

+ 1 - 0
atom/browser/native_window_observer.h

@@ -78,6 +78,7 @@ class NativeWindowObserver {
   virtual void OnWindowLeaveHtmlFullScreen() {}
   virtual void OnTouchBarItemResult(const std::string& item_id,
                                     const base::DictionaryValue& details) {}
+  virtual void OnNewWindowForTab() {}
 
   // Called when window message received
   #if defined(OS_WIN)

+ 10 - 0
docs/api/app.md

@@ -149,6 +149,16 @@ ID as the activity's source app and that supports the activity's type.
 Supported activity types are specified in the app's `Info.plist` under the
 `NSUserActivityTypes` key.
 
+### Event: 'new-window-for-tab' _macOS_
+
+Returns:
+
+* `event` Event
+
+Emitted when the user clicks the native macOS new tab button. The new
+tab button is only visible if the current `BrowserWindow` has a
+`tabbingIdentifier`
+
 ### Event: 'browser-window-blur'
 
 Returns:

+ 7 - 1
docs/api/browser-window.md

@@ -239,7 +239,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`.
     `maximize()` directly. Default is `false`.
   * `tabbingIdentifier` String (optional) - Tab group name, allows opening the
     window as a native tab on macOS 10.12+. Windows with the same tabbing
-    identifier will be grouped together.
+    identifier will be grouped together. This also adds a native new tab button
+    to your window's tab bar and allows your `app` and window to receive the
+    `new-window-for-tab` event.
   * `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
@@ -547,6 +549,10 @@ Emitted when the window opens a sheet.
 
 Emitted when the window has closed a sheet.
 
+#### Event: 'new-window-for-tab' _macOS_
+
+Emitted when the native new tab button is clicked.
+
 ### Static Methods
 
 The `BrowserWindow` class has the following static methods: