From d8679b38993ae66c9e6d60968da19124005d09b6 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 2 Feb 2016 23:01:00 -0800 Subject: [PATCH] Allow openExternal to open URLs in the background #3224 --- .../atom_resource_dispatcher_host_delegate.cc | 2 +- atom/common/api/atom_api_shell.cc | 12 +++++++++++- atom/common/platform_util.h | 2 +- atom/common/platform_util_linux.cc | 2 +- atom/common/platform_util_mac.mm | 12 ++++++++++-- atom/common/platform_util_win.cc | 2 +- docs/api/shell.md | 10 ++++++++-- 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/atom/browser/atom_resource_dispatcher_host_delegate.cc b/atom/browser/atom_resource_dispatcher_host_delegate.cc index aaba1f31045b..33e90671aba8 100644 --- a/atom/browser/atom_resource_dispatcher_host_delegate.cc +++ b/atom/browser/atom_resource_dispatcher_host_delegate.cc @@ -26,7 +26,7 @@ bool AtomResourceDispatcherHostDelegate::HandleExternalProtocol( bool has_user_gesture) { GURL escaped_url(net::EscapeExternalHandlerValue(url.spec())); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url)); + base::Bind(base::IgnoreResult(platform_util::OpenExternal), escaped_url, false)); return true; } diff --git a/atom/common/api/atom_api_shell.cc b/atom/common/api/atom_api_shell.cc index a4599ee0c359..d479911fbe32 100644 --- a/atom/common/api/atom_api_shell.cc +++ b/atom/common/api/atom_api_shell.cc @@ -12,12 +12,22 @@ namespace { +bool OpenExternal(const GURL& url, mate::Arguments* args) { + bool without_activation = false; + if (args->Length() == 2) { + mate::Dictionary options; + args->GetNext(&options); + options.Get("withoutActivation", &without_activation); + } + return platform_util::OpenExternal(url, without_activation); +} + void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { mate::Dictionary dict(context->GetIsolate(), exports); dict.SetMethod("showItemInFolder", &platform_util::ShowItemInFolder); dict.SetMethod("openItem", &platform_util::OpenItem); - dict.SetMethod("openExternal", &platform_util::OpenExternal); + dict.SetMethod("openExternal", &OpenExternal); dict.SetMethod("moveItemToTrash", &platform_util::MoveItemToTrash); dict.SetMethod("beep", &platform_util::Beep); } diff --git a/atom/common/platform_util.h b/atom/common/platform_util.h index 312942c4f5dc..3550c243bb68 100644 --- a/atom/common/platform_util.h +++ b/atom/common/platform_util.h @@ -23,7 +23,7 @@ void OpenItem(const base::FilePath& full_path); // Open the given external protocol URL in the desktop's default manner. // (For example, mailto: URLs in the default mail user agent.) -bool OpenExternal(const GURL& url); +bool OpenExternal(const GURL& url, const bool without_activation); // Move a file to trash. bool MoveItemToTrash(const base::FilePath& full_path); diff --git a/atom/common/platform_util_linux.cc b/atom/common/platform_util_linux.cc index aa7439968daa..fd4dcba6973b 100644 --- a/atom/common/platform_util_linux.cc +++ b/atom/common/platform_util_linux.cc @@ -64,7 +64,7 @@ void OpenItem(const base::FilePath& full_path) { XDGOpen(full_path.value()); } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { if (url.SchemeIs("mailto")) return XDGEmail(url.spec()); else diff --git a/atom/common/platform_util_mac.mm b/atom/common/platform_util_mac.mm index 7184593ae190..e84b3fbec307 100644 --- a/atom/common/platform_util_mac.mm +++ b/atom/common/platform_util_mac.mm @@ -119,7 +119,7 @@ void OpenItem(const base::FilePath& full_path) { } } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { DCHECK([NSThread isMainThread]); NSURL* ns_url = net::NSURLWithGURL(url); if (!ns_url) { @@ -136,7 +136,15 @@ bool OpenExternal(const GURL& url) { } CFRelease(openingApp); // NOT A BUG; LSGetApplicationForURL retains for us - return [[NSWorkspace sharedWorkspace] openURL:ns_url]; + NSUInteger launchOptions = NSWorkspaceLaunchDefault; + if (without_activation) + launchOptions = launchOptions | NSWorkspaceLaunchWithoutActivation; + + return [[NSWorkspace sharedWorkspace] openURLs: @[ns_url] + withAppBundleIdentifier: nil + options: launchOptions + additionalEventParamDescriptor: NULL + launchIdentifiers: NULL]; } bool MoveItemToTrash(const base::FilePath& full_path) { diff --git a/atom/common/platform_util_win.cc b/atom/common/platform_util_win.cc index 4de5224668b6..76b71cb7f702 100644 --- a/atom/common/platform_util_win.cc +++ b/atom/common/platform_util_win.cc @@ -301,7 +301,7 @@ void OpenItem(const base::FilePath& full_path) { ui::win::OpenFileViaShell(full_path); } -bool OpenExternal(const GURL& url) { +bool OpenExternal(const GURL& url, const bool without_activation) { // Quote the input scheme to be sure that the command does not have // parameters unexpected by the external program. This url should already // have been escaped. diff --git a/docs/api/shell.md b/docs/api/shell.md index e6678a955364..a7f03a52f9c7 100644 --- a/docs/api/shell.md +++ b/docs/api/shell.md @@ -26,12 +26,18 @@ Show the given file in a file manager. If possible, select the file. Open the given file in the desktop's default manner. -### `shell.openExternal(url)` +### `shell.openExternal(url[, options])` * `url` String Open the given external protocol URL in the desktop's default manner. (For -example, mailto: URLs in the user's default mail agent.) +example, mailto: URLs in the user's default mail agent.) Returns true if an +application was available to open the URL, false otherwise. + +On Mac OS X, you can pass additional options to openExternal: + +- withoutActivation: Pass true to open the URL without bringing the + application into the foreground. ### `shell.moveItemToTrash(fullPath)`