mirror of
https://github.com/transmission/transmission.git
synced 2025-12-20 02:18:42 +00:00
refactor: move macOS default app logic to dedicated class (#6120)
This commit is contained in:
committed by
GitHub
parent
aa307d5696
commit
1c18737e67
@@ -449,6 +449,7 @@
|
||||
ED20B87C28589274005FA6BE /* common_defs.h in Headers */ = {isa = PBXBuildFile; fileRef = ED20B87B28589274005FA6BE /* common_defs.h */; };
|
||||
ED20B87F285892C5005FA6BE /* crc32_multipliers.h in Headers */ = {isa = PBXBuildFile; fileRef = ED20B87D285892C5005FA6BE /* crc32_multipliers.h */; };
|
||||
ED20B880285892C5005FA6BE /* crc32_tables.h in Headers */ = {isa = PBXBuildFile; fileRef = ED20B87E285892C5005FA6BE /* crc32_tables.h */; };
|
||||
ED86936F2ADAE34D00342B1A /* DefaultAppHelper.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */; };
|
||||
ED8A163F2735A8AA000D61F9 /* peer-mgr-active-requests.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8A163B2735A8AA000D61F9 /* peer-mgr-active-requests.h */; };
|
||||
ED8A16402735A8AA000D61F9 /* peer-mgr-active-requests.cc in Sources */ = {isa = PBXBuildFile; fileRef = ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */; };
|
||||
ED8A16412735A8AA000D61F9 /* peer-mgr-wishlist.h in Headers */ = {isa = PBXBuildFile; fileRef = ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */; };
|
||||
@@ -1236,6 +1237,8 @@
|
||||
ED20B87B28589274005FA6BE /* common_defs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common_defs.h; sourceTree = "<group>"; };
|
||||
ED20B87D285892C5005FA6BE /* crc32_multipliers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32_multipliers.h; path = lib/crc32_multipliers.h; sourceTree = "<group>"; };
|
||||
ED20B87E285892C5005FA6BE /* crc32_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crc32_tables.h; path = lib/crc32_tables.h; sourceTree = "<group>"; };
|
||||
ED86936D2ADAE34D00342B1A /* DefaultAppHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DefaultAppHelper.h; sourceTree = "<group>"; };
|
||||
ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DefaultAppHelper.mm; sourceTree = "<group>"; };
|
||||
ED8A163B2735A8AA000D61F9 /* peer-mgr-active-requests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "peer-mgr-active-requests.h"; sourceTree = "<group>"; };
|
||||
ED8A163C2735A8AA000D61F9 /* peer-mgr-active-requests.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "peer-mgr-active-requests.cc"; sourceTree = "<group>"; };
|
||||
ED8A163D2735A8AA000D61F9 /* peer-mgr-wishlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "peer-mgr-wishlist.h"; sourceTree = "<group>"; };
|
||||
@@ -1537,6 +1540,8 @@
|
||||
A222E9860E6B21D9009FB003 /* BlocklistDownloaderViewController.mm */,
|
||||
A222EA790E6C32C4009FB003 /* BlocklistScheduler.h */,
|
||||
A222EA7A0E6C32C4009FB003 /* BlocklistScheduler.mm */,
|
||||
ED86936D2ADAE34D00342B1A /* DefaultAppHelper.h */,
|
||||
ED86936E2ADAE34D00342B1A /* DefaultAppHelper.mm */,
|
||||
A2AB883916A399A6008FAD50 /* VDKQueue */,
|
||||
);
|
||||
name = Sources;
|
||||
@@ -3078,6 +3083,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C86BCD9928228A9600F45599 /* SparkleProxy.mm in Sources */,
|
||||
ED86936F2ADAE34D00342B1A /* DefaultAppHelper.mm in Sources */,
|
||||
A225A4C0187E369C00CDE823 /* ShareToolbarItem.mm in Sources */,
|
||||
A2D77453154CC72B00A62B93 /* WebSeedTableView.mm in Sources */,
|
||||
8D11072D0486CEB800E47090 /* main.mm in Sources */,
|
||||
|
||||
@@ -62,6 +62,8 @@ target_sources(${TR_NAME}-mac
|
||||
Controller.mm
|
||||
CreatorWindowController.h
|
||||
CreatorWindowController.mm
|
||||
DefaultAppHelper.h
|
||||
DefaultAppHelper.mm
|
||||
DragOverlayView.h
|
||||
DragOverlayView.mm
|
||||
DragOverlayWindow.h
|
||||
|
||||
15
macosx/DefaultAppHelper.h
Normal file
15
macosx/DefaultAppHelper.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// This file Copyright © 2007-2023 Transmission authors and contributors.
|
||||
// It may be used under the MIT (SPDX: MIT) license.
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface DefaultAppHelper : NSObject
|
||||
|
||||
- (BOOL)isDefaultForTorrentFiles;
|
||||
- (void)setDefaultForTorrentFiles:(void (^_Nullable)())completionHandler;
|
||||
|
||||
- (BOOL)isDefaultForMagnetURLs;
|
||||
- (void)setDefaultForMagnetURLs:(void (^_Nullable)())completionHandler;
|
||||
|
||||
@end
|
||||
183
macosx/DefaultAppHelper.mm
Normal file
183
macosx/DefaultAppHelper.mm
Normal file
@@ -0,0 +1,183 @@
|
||||
// This file Copyright © 2007-2023 Transmission authors and contributors.
|
||||
// It may be used under the MIT (SPDX: MIT) license.
|
||||
// License text can be found in the licenses/ folder.
|
||||
|
||||
#import "DefaultAppHelper.h"
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
|
||||
static NSString* const kMagnetURLScheme = @"magnet";
|
||||
static NSString* const kTorrentFileType = @"org.bittorrent.torrent";
|
||||
|
||||
UTType* GetTorrentFileType(void) API_AVAILABLE(macos(11.0))
|
||||
{
|
||||
static UTType* result = nil;
|
||||
|
||||
static dispatch_once_t once;
|
||||
dispatch_once(&once, ^{
|
||||
result = [UTType exportedTypeWithIdentifier:kTorrentFileType conformingToType:UTTypeData];
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@interface DefaultAppHelper ()
|
||||
|
||||
@property(nonatomic, readonly) NSString* bundleIdentifier;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DefaultAppHelper
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_bundleIdentifier = NSBundle.mainBundle.bundleIdentifier;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isDefaultForTorrentFiles
|
||||
{
|
||||
if (@available(macOS 12, *))
|
||||
{
|
||||
UTType* fileType = GetTorrentFileType();
|
||||
NSURL* appUrl = [NSWorkspace.sharedWorkspace URLForApplicationToOpenContentType:fileType];
|
||||
if (!appUrl)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString* bundleId = [NSBundle bundleWithURL:appUrl].bundleIdentifier;
|
||||
|
||||
if ([self.bundleIdentifier isEqualToString:bundleId])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString* bundleId = (__bridge NSString*)LSCopyDefaultRoleHandlerForContentType((__bridge CFStringRef)kTorrentFileType, kLSRolesViewer);
|
||||
if (!bundleId)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([self.bundleIdentifier isEqualToString:bundleId])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setDefaultForTorrentFiles:(void (^_Nullable)())completionHandler
|
||||
{
|
||||
if (@available(macOS 12, *))
|
||||
{
|
||||
UTType* fileType = GetTorrentFileType();
|
||||
NSURL* appUrl = [NSWorkspace.sharedWorkspace URLForApplicationWithBundleIdentifier:self.bundleIdentifier];
|
||||
[NSWorkspace.sharedWorkspace setDefaultApplicationAtURL:appUrl toOpenContentType:fileType completionHandler:^(NSError* error) {
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"Failed setting default torrent file handler: %@", error.localizedDescription);
|
||||
}
|
||||
if (completionHandler != nil)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionHandler();
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
OSStatus const result = LSSetDefaultRoleHandlerForContentType(
|
||||
(__bridge CFStringRef)kTorrentFileType,
|
||||
kLSRolesViewer,
|
||||
(__bridge CFStringRef)self.bundleIdentifier);
|
||||
if (result != noErr)
|
||||
{
|
||||
NSLog(@"Failed setting default torrent file handler");
|
||||
}
|
||||
if (completionHandler != nil)
|
||||
{
|
||||
completionHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isDefaultForMagnetURLs
|
||||
{
|
||||
if (@available(macOS 12, *))
|
||||
{
|
||||
NSURL* schemeUrl = [NSURL URLWithString:[kMagnetURLScheme stringByAppendingString:@":"]];
|
||||
NSURL* appUrl = [NSWorkspace.sharedWorkspace URLForApplicationToOpenURL:schemeUrl];
|
||||
if (!appUrl)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSString* bundleId = [NSBundle bundleWithURL:appUrl].bundleIdentifier;
|
||||
|
||||
if ([self.bundleIdentifier isEqualToString:bundleId])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString* bundleId = (__bridge NSString*)LSCopyDefaultHandlerForURLScheme((__bridge CFStringRef)kMagnetURLScheme);
|
||||
if (!bundleId)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if ([self.bundleIdentifier isEqualToString:bundleId])
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setDefaultForMagnetURLs:(void (^_Nullable)())completionHandler
|
||||
{
|
||||
if (@available(macOS 12, *))
|
||||
{
|
||||
NSURL* appUrl = [NSWorkspace.sharedWorkspace URLForApplicationWithBundleIdentifier:self.bundleIdentifier];
|
||||
[NSWorkspace.sharedWorkspace setDefaultApplicationAtURL:appUrl toOpenURLsWithScheme:kMagnetURLScheme
|
||||
completionHandler:^(NSError* error) {
|
||||
if (error)
|
||||
{
|
||||
NSLog(@"Failed setting default magnet link handler: %@", error.localizedDescription);
|
||||
}
|
||||
if (completionHandler != nil)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionHandler();
|
||||
});
|
||||
}
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
OSStatus const result = LSSetDefaultHandlerForURLScheme(
|
||||
(__bridge CFStringRef)kMagnetURLScheme,
|
||||
(__bridge CFStringRef)self.bundleIdentifier);
|
||||
if (result != noErr)
|
||||
{
|
||||
NSLog(@"Failed setting default magnet link handler");
|
||||
}
|
||||
if (completionHandler != nil)
|
||||
{
|
||||
completionHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -11,6 +11,7 @@
|
||||
#import "BlocklistDownloaderViewController.h"
|
||||
#import "BlocklistScheduler.h"
|
||||
#import "Controller.h"
|
||||
#import "DefaultAppHelper.h"
|
||||
#import "PortChecker.h"
|
||||
#import "BonjourController.h"
|
||||
#import "NSImageAdditions.h"
|
||||
@@ -103,6 +104,7 @@ static NSString* const kWebUIURLFormat = @"http://localhost:%ld/";
|
||||
@property(nonatomic, readonly) NSMutableArray<NSString*>* fRPCWhitelistArray;
|
||||
@property(nonatomic) IBOutlet NSSegmentedControl* fRPCAddRemoveControl;
|
||||
@property(nonatomic, copy) NSString* fRPCPassword;
|
||||
@property(nonatomic, readonly) DefaultAppHelper* fDefaultAppHelper;
|
||||
|
||||
@end
|
||||
|
||||
@@ -177,6 +179,8 @@ static NSString* const kWebUIURLFormat = @"http://localhost:%ld/";
|
||||
}
|
||||
|
||||
[self setAutoUpdateToBeta:nil];
|
||||
|
||||
_fDefaultAppHelper = [[DefaultAppHelper alloc] init];
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -215,7 +219,7 @@ static NSString* const kWebUIURLFormat = @"http://localhost:%ld/";
|
||||
|
||||
[self setPrefView:nil];
|
||||
|
||||
[self updateDefaultsStatus];
|
||||
[self updateDefaultsStates];
|
||||
|
||||
//set special-handling of magnet link add window checkbox
|
||||
[self updateShowAddMagnetWindowField];
|
||||
@@ -859,55 +863,27 @@ static NSString* const kWebUIURLFormat = @"http://localhost:%ld/";
|
||||
|
||||
- (IBAction)setDefaultForMagnets:(id)sender
|
||||
{
|
||||
NSString* bundleID = NSBundle.mainBundle.bundleIdentifier;
|
||||
OSStatus const result = LSSetDefaultHandlerForURLScheme((CFStringRef) @"magnet", (__bridge CFStringRef)bundleID);
|
||||
if (result != noErr)
|
||||
{
|
||||
NSLog(@"Failed setting default magnet link handler");
|
||||
}
|
||||
[self updateDefaultsStatus];
|
||||
PrefsController* __weak weakSelf = self;
|
||||
[self.fDefaultAppHelper setDefaultForMagnetURLs:^{
|
||||
[weakSelf updateDefaultsStates];
|
||||
}];
|
||||
}
|
||||
|
||||
- (IBAction)setDefaultForTorrentFiles:(id)sender
|
||||
{
|
||||
NSString* bundleID = NSBundle.mainBundle.bundleIdentifier;
|
||||
OSStatus const result = LSSetDefaultRoleHandlerForContentType((CFStringRef) @"org.bittorrent.torrent", kLSRolesViewer, (__bridge CFStringRef)bundleID);
|
||||
if (result != noErr)
|
||||
{
|
||||
NSLog(@"Failed setting default torrent file handler");
|
||||
}
|
||||
[self updateDefaultsStatus];
|
||||
PrefsController* __weak weakSelf = self;
|
||||
[self.fDefaultAppHelper setDefaultForTorrentFiles:^{
|
||||
[weakSelf updateDefaultsStates];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)updateDefaultsStatus
|
||||
- (void)updateDefaultsStates
|
||||
{
|
||||
BOOL isDefaultForMagnetSet = NO;
|
||||
BOOL isDefaultForTorrentSet = NO;
|
||||
BOOL const isDefaultForMagnetURLs = [self.fDefaultAppHelper isDefaultForMagnetURLs];
|
||||
self.fSetDefaultForMagnetButton.enabled = !isDefaultForMagnetURLs;
|
||||
|
||||
NSString* bundleID = NSBundle.mainBundle.bundleIdentifier;
|
||||
|
||||
NSString* const defaultBundleIdForMagnet = (__bridge NSString*)LSCopyDefaultHandlerForURLScheme((CFStringRef) @"magnet");
|
||||
if (defaultBundleIdForMagnet)
|
||||
{
|
||||
if ([bundleID isEqualToString:defaultBundleIdForMagnet])
|
||||
{
|
||||
isDefaultForMagnetSet = YES;
|
||||
}
|
||||
}
|
||||
|
||||
NSString* const defaultBundleIdForTorrent = (__bridge NSString*)LSCopyDefaultRoleHandlerForContentType(
|
||||
(CFStringRef) @"org.bittorrent.torrent",
|
||||
kLSRolesViewer);
|
||||
if (defaultBundleIdForTorrent)
|
||||
{
|
||||
if ([bundleID isEqualToString:defaultBundleIdForTorrent])
|
||||
{
|
||||
isDefaultForTorrentSet = YES;
|
||||
}
|
||||
}
|
||||
|
||||
self.fSetDefaultForMagnetButton.enabled = !isDefaultForMagnetSet;
|
||||
self.fSetDefaultForTorrentButton.enabled = !isDefaultForTorrentSet;
|
||||
BOOL const isDefaultForTorrentFiles = [self.fDefaultAppHelper isDefaultForTorrentFiles];
|
||||
self.fSetDefaultForTorrentButton.enabled = !isDefaultForTorrentFiles;
|
||||
}
|
||||
|
||||
- (void)setQueue:(id)sender
|
||||
|
||||
Reference in New Issue
Block a user