From 19d5d3b7d185dd42521b062b135e14c08732d5f6 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sat, 7 May 2016 11:07:58 -0700 Subject: [PATCH 1/2] Implement RemoveAsDefaultProtocolClient on OS X --- atom/browser/browser_mac.mm | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index eb7191b67a2..767ddee590e 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -43,7 +43,28 @@ void Browser::ClearRecentDocuments() { } bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { - return false; + NSString* identifier = [base::mac::MainBundle() bundleIdentifier]; + if (!identifier) + return false; + + NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()]; + CFStringRef protocol_cf = base::mac::NSToCFCast(protocol_ns); + CFArrayRef bundleList = LSCopyAllHandlersForURLScheme(protocol_cf); + if (!bundleList) { + return false; + } + // On Mac OS X, we can't query the default, but the handlers list seems to put + // Apple's defaults first, so we'll use the first option that isn't our bundle + CFStringRef other = nil; + for (CFIndex i = 0; i < CFArrayGetCount(bundleList); i++) { + other = (CFStringRef)CFArrayGetValueAtIndex(bundleList, i); + if (![identifier isEqualToString: (__bridge NSString *)other]) { + break; + } + } + + OSStatus return_code = LSSetDefaultHandlerForURLScheme(protocol_cf, other); + return return_code == noErr; } bool Browser::SetAsDefaultProtocolClient(const std::string& protocol) { From ac905e708009d17cf048c296e802f68c21a6a721 Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Sun, 8 May 2016 10:50:17 -0700 Subject: [PATCH 2/2] Add docs, avoid side effects when not currently default --- atom/browser/browser_mac.mm | 3 +++ docs/api/app.md | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atom/browser/browser_mac.mm b/atom/browser/browser_mac.mm index 767ddee590e..3cabd98b692 100644 --- a/atom/browser/browser_mac.mm +++ b/atom/browser/browser_mac.mm @@ -47,6 +47,9 @@ bool Browser::RemoveAsDefaultProtocolClient(const std::string& protocol) { if (!identifier) return false; + if (!Browser::IsDefaultProtocolClient(protocol)) + return false; + NSString* protocol_ns = [NSString stringWithUTF8String:protocol.c_str()]; CFStringRef protocol_cf = base::mac::NSToCFCast(protocol_ns); CFArrayRef bundleList = LSCopyAllHandlersForURLScheme(protocol_cf); diff --git a/docs/api/app.md b/docs/api/app.md index c6c5887ef62..cb19b49b7c1 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -393,16 +393,13 @@ Please refer to [Apple's documentation][CFBundleURLTypes] for details. The API uses the Windows Registry and LSSetDefaultHandlerForURLScheme internally. -### `app.removeAsDefaultProtocolClient(protocol)` _Windows_ +### `app.removeAsDefaultProtocolClient(protocol)` _OS X_ _Windows_ * `protocol` String - The name of your protocol, without `://`. This method checks if the current executable as the default handler for a protocol (aka URI scheme). If so, it will remove the app as the default handler. -**Note:** On OS X, removing the app will automatically remove the app as the -default protocol handler. - ### `app.isDefaultProtocolClient(protocol)` _OS X_ _Windows_ * `protocol` String - The name of your protocol, without `://`.