diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index f7e362c68..447d5b4cf 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -33,6 +33,7 @@ struct AppDefaults { static let addFolderAccountID = "addFolderAccountID" static let importOPMLAccountID = "importOPMLAccountID" static let exportOPMLAccountID = "exportOPMLAccountID" + static let defaultBrowserID = "defaultBrowserID" // Hidden prefs static let showDebugMenu = "ShowDebugMenu" @@ -171,6 +172,15 @@ struct AppDefaults { setString(for: Key.exportOPMLAccountID, newValue) } } + + static var defaultBrowserID: String? { + get { + return string(for: Key.defaultBrowserID) + } + set { + setString(for: Key.defaultBrowserID, newValue) + } + } static var showTitleOnMainWindow: Bool { return bool(for: Key.showTitleOnMainWindow) diff --git a/Mac/Base.lproj/Preferences.storyboard b/Mac/Base.lproj/Preferences.storyboard index a1e976819..0c90be9b1 100644 --- a/Mac/Base.lproj/Preferences.storyboard +++ b/Mac/Base.lproj/Preferences.storyboard @@ -1,7 +1,7 @@ - + - + @@ -30,15 +30,15 @@ - - + + - + - + @@ -46,7 +46,7 @@ - + @@ -81,7 +81,7 @@ - + @@ -89,7 +89,7 @@ - + @@ -103,14 +103,6 @@ - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + @@ -178,15 +193,16 @@ - + + - - + + @@ -196,10 +212,12 @@ + + - + @@ -210,13 +228,14 @@ + - + @@ -396,16 +415,16 @@ - + - + - + - + @@ -512,7 +531,7 @@ - + @@ -567,16 +586,16 @@ - + - + - + - + @@ -679,7 +698,7 @@ - + diff --git a/Mac/Browser.swift b/Mac/Browser.swift index b36a27ea0..f8e4b0cea 100644 --- a/Mac/Browser.swift +++ b/Mac/Browser.swift @@ -11,14 +11,44 @@ import RSWeb struct Browser { + /// The user-specified default browser for opening web pages. + /// + /// The user-assigned default browser, or `nil` if none was assigned + /// (i.e., the system default should be used). + static var defaultBrowser: MacWebBrowser? { + if let bundleID = AppDefaults.defaultBrowserID, let browser = MacWebBrowser(bundleIdentifier: bundleID) { + return browser + } + + return nil + } + + + /// Opens a URL in the default browser. + /// + /// - Parameters: + /// - urlString: The URL to open. + /// - invert: Whether to invert the "open in background in browser" preference static func open(_ urlString: String, invertPreference invert: Bool = false) { // Opens according to prefs. open(urlString, inBackground: invert ? !AppDefaults.openInBrowserInBackground : AppDefaults.openInBrowserInBackground) } + + /// Opens a URL in the default browser. + /// + /// - Parameters: + /// - urlString: The URL to open. + /// - inBackground: Whether to open the URL in the background or not. + /// - Note: Some browsers (specifically Chromium-derived ones) will ignore the request + /// to open in the background. static func open(_ urlString: String, inBackground: Bool) { if let url = URL(string: urlString) { - MacWebBrowser.openURL(url, inBackground: inBackground) + if let defaultBrowser = defaultBrowser { + defaultBrowser.openURL(url, inBackground: inBackground) + } else { + MacWebBrowser.openURL(url, inBackground: inBackground) + } } } } diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index 4e2a74f88..4d068daad 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -92,6 +92,7 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { DispatchQueue.main.async { self.updateWindowTitle() } + } // MARK: - API @@ -166,7 +167,7 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { } } - + // MARK: - Toolbar @objc func makeToolbarValidate() { diff --git a/Mac/Preferences/General/GeneralPrefencesViewController.swift b/Mac/Preferences/General/GeneralPrefencesViewController.swift index 57996a485..9ea450cbb 100644 --- a/Mac/Preferences/General/GeneralPrefencesViewController.swift +++ b/Mac/Preferences/General/GeneralPrefencesViewController.swift @@ -8,10 +8,12 @@ import AppKit import RSCore +import RSWeb final class GeneralPreferencesViewController: NSViewController { @IBOutlet var defaultRSSReaderPopup: NSPopUpButton! + @IBOutlet var defaultBrowserPopup: NSPopUpButton! private var rssReaderInfo = RSSReaderInfo() public override init(nibName nibNameOrNil: NSNib.Name?, bundle nibBundleOrNil: Bundle?) { @@ -47,6 +49,15 @@ final class GeneralPreferencesViewController: NSViewController { registerAppWithBundleID(bundleID) updateUI() } + + @IBAction func browserPopUpDidChangeValue(_ sender: Any?) { + guard let menuItem = defaultBrowserPopup.selectedItem else { + return + } + let bundleID = menuItem.representedObject as? String + AppDefaults.defaultBrowserID = bundleID + updateUI() + } } // MARK: - Private @@ -60,6 +71,7 @@ private extension GeneralPreferencesViewController { func updateUI() { rssReaderInfo = RSSReaderInfo() updateRSSReaderPopup() + updateBrowserPopup() } func updateRSSReaderPopup() { @@ -123,6 +135,37 @@ private extension GeneralPreferencesViewController { NSWorkspace.shared.setDefaultAppBundleID(forURLScheme: "feed", to: bundleID) NSWorkspace.shared.setDefaultAppBundleID(forURLScheme: "feeds", to: bundleID) } + + func updateBrowserPopup() { + let menu = defaultBrowserPopup.menu! + let allBrowsers = MacWebBrowser.sortedBrowsers() + + menu.removeAllItems() + + let defaultBrowser = MacWebBrowser.default + + let defaultBrowserFormat = NSLocalizedString("System Default (%@)", comment: "Default browser item title format") + let defaultBrowserTitle = String(format: defaultBrowserFormat, defaultBrowser.name!) + let item = NSMenuItem(title: defaultBrowserTitle, action: nil, keyEquivalent: "") + let icon = defaultBrowser.icon! + icon.size = NSSize(width: 16.0, height: 16.0) + item.image = icon + + menu.addItem(item) + menu.addItem(NSMenuItem.separator()) + + for browser in allBrowsers { + let item = NSMenuItem(title: browser.name!, action: nil, keyEquivalent: "") + item.representedObject = browser.bundleIdentifier + + let icon = browser.icon! + icon.size = NSSize(width: 16.0, height: 16.0) + item.image = browser.icon + menu.addItem(item) + } + + defaultBrowserPopup.selectItem(at: defaultBrowserPopup.indexOfItem(withRepresentedObject: AppDefaults.defaultBrowserID)) + } } diff --git a/submodules/RSWeb b/submodules/RSWeb index 05388e4f7..90636c645 160000 --- a/submodules/RSWeb +++ b/submodules/RSWeb @@ -1 +1 @@ -Subproject commit 05388e4f7073b014f786cfce18782c3d61f8e378 +Subproject commit 90636c6458eaf883e6e890dfc46ae6c65530e2fe