diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index 8f2d08277ae..127a1c984ef 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/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, diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index f9726594350..01d45d383f1 100644 --- a/atom/browser/api/atom_api_app.h +++ b/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: diff --git a/atom/browser/api/atom_api_window.cc b/atom/browser/api/atom_api_window.cc index 6862915f9cf..54289d872f1 100644 --- a/atom/browser/api/atom_api_window.cc +++ b/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)) { diff --git a/atom/browser/api/atom_api_window.h b/atom/browser/api/atom_api_window.h index 75f0328ba64..26ff95a6111 100644 --- a/atom/browser/api/atom_api_window.h +++ b/atom/browser/api/atom_api_window.h @@ -91,6 +91,7 @@ class Window : public mate::TrackableObject, 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; diff --git a/atom/browser/browser.cc b/atom/browser/browser.cc index b2900a326ff..c714dc1f46a 100644 --- a/atom/browser/browser.cc +++ b/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 diff --git a/atom/browser/browser.h b/atom/browser/browser.h index 78cac65f7e4..2204eafdd55 100644 --- a/atom/browser/browser.h +++ b/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); diff --git a/atom/browser/browser_observer.h b/atom/browser/browser_observer.h index 88a50a93a7e..3e50fc228b9 100644 --- a/atom/browser/browser_observer.h +++ b/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: diff --git a/atom/browser/mac/atom_application_delegate.mm b/atom/browser/mac/atom_application_delegate.mm index 4c6a938fba5..1ad07a90869 100644 --- a/atom/browser/mac/atom_application_delegate.mm +++ b/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 diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index f06841cb67a..ddb4a030079 100644 --- a/atom/browser/native_window.cc +++ b/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) { diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 89eacdb05d7..dd874057895 100644 --- a/atom/browser/native_window.h +++ b/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); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index f46400ec0b0..2e89d5e838a 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -7,6 +7,7 @@ #include #include +#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 diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 8c908dc8237..9aad030aa32 100644 --- a/atom/browser/native_window_observer.h +++ b/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) diff --git a/docs/api/app.md b/docs/api/app.md index 784b20a4730..d8bf485808f 100644 --- a/docs/api/app.md +++ b/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: diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 468cdd29257..b00245e8317 100644 --- a/docs/api/browser-window.md +++ b/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: