Jump to content

Set Default Browser


Recommended Posts

Posted (edited)

icon.png
Default Browser

An Alfred workflow to set the default web browser. 

 

▸ Visit on Github ◂ | ▸ Alfred Gallery ◂

 


Usage Note

  • Set the default web browser using the keyword (default: sdb).
  • The macOS browser change confirmation dialog is automatically accepted.

Utility: Use the workflow’s File Action (name: Bundle Identifier Information) to retrieve an application’s bundle identifier.

 

sdb1.png

sdb2.png

sdb3.png

Edited by zeitlings
v1.3.0
Posted

Would it not be doable to have it use /usr/bin/swift in the Run Script with your code inside? That way users wouldn’t need to compile it themselves (seeing as the binary is not signed and notarised) and it could go in the Alfred Gallery.

Posted (edited)

I'm not registered with the AppStore, unfortunately, so no notarization for me. It did not even occur to me not to compile it, though. It's definitely doable, the program is simple enough. Give me a second.

Edited by zeitlings
Posted (edited)

v1.2.0 

  • Added File Action utility to get bundle identifiers from apps
  • Added useful failure messages
  • Added configurable keyword
  • Added more default options
  • Added new icon
  • Updated documentation
Edited by zeitlings
  • 2 months later...
Posted

@zeitlingsThanks for this workflow. 

 

Quick question. When triggered, I think the workflow takes 3-4 seconds to show the brlow popup and then click the "Use <Browser>" button. Is that how it is expected to work. Because the other day I triggered it and start typing something (thinking this browser has been changed in the background) and the popup showed up at the same time I pressed the Tab key, that changed the focus. 

 

 

 

 

image.thumb.png.5c5e6c3c08e03d547a8659fe008c85d4.png

Posted

@andy4222 That is probably the Apple Script taking some time to wake up. MacOS will always ask you if you are sure you want to change the browser. The script focuses that modal window and "clicks" the button to accept the change. If you're switching to an another window before that has happened, the script will fail. So yeah, there might be a delay (also for the swift script to execute if it is called the first time after a while; after that it seems to be cached somewhere and executes faster.)

  • 3 weeks later...
Posted

 

On 1/19/2023 at 5:23 PM, zeitlings said:

Add the browsers you’re missing to the list filter and provide the bundle identifiers for them, or remove the ones that you don’t need.

 

You can add a checkbox list in User Configuration so we can uncheck the browsers we don't want listed.

  • 3 weeks later...
Posted (edited)
On 7/26/2023 at 1:53 AM, xilopaint said:

You can add a checkbox list in User Configuration so we can uncheck the browsers we don't want listed.

 

Sure, why not 😄

 

v1.3.0

- Added browser selection to workflow configuration 

 

Edited by zeitlings
v1.3.0
  • 2 weeks later...
Posted

If it can handle http URLs, it should be possible. With v1.2.0 you can just throw it into the List Filter and check if it works. 

There is the "Bundle Identifier Information" Universal Action to find the bundle identifier if you need it.

Posted
42 minutes ago, zeitlings said:

If it can handle http URLs, it should be possible. With v1.2.0 you can just throw it into the List Filter and check if it works. 

There is the "Bundle Identifier Information" Universal Action to find the bundle identifier if you need it.

 

Do you need me to check anything to add native support?

  • 6 months later...
Posted

Thanks for your wonderful workflow. I use it to switch between Safari, Arc, Firefox and Ghost browser. I was able to add Ghost browser using you bundle identifier and manually modify the appropiate files (info.plist, list.sh) and add an icon.

  • 1 month later...
Posted
On 1/20/2023 at 8:08 AM, vitor said:

Will be live in the Gallery soon at http://alfred.app/workflows/zeitlings/set-default-browser/.

 

Thank you for the workflow!

Cos of you - i upgraded to Alfred 5 so I can make use of your nifty feature :)

 

TLDR; In case someone is reading and like to know why should you regularly change web browser ?
It's part of compartmentalization principle of keeping things together...

In this case, 1 web browser is for work (so all web browsing history and suggestions are from my work related internal webpages) and another web browser for something else..

  • 5 months later...
Posted

It's not working for me on Mac OS 15.1, Alfred 5.5.1

Debug output is 

[11:42:17.276] Default Browser[Script Filter] Queuing argument '(null)'
[11:42:17.544] Default Browser[Script Filter] Script with argv '(null)' finished
[11:42:17.548] Default Browser[Script Filter] {
    "items": [
        {
            "title":"Safari",
            "arg":"com.apple.Safari",
            "icon":{
                "path":"icons/com.apple.Safari.png"
            }
        },{
            "title":"Chrome",
            "arg":"com.google.Chrome",
            "icon":{
                "path":"icons/com.google.Chrome.png"
            }
        },
    ]
}
[11:42:23.816] Default Browser[Script Filter] Processing complete
[11:42:23.819] Default Browser[Script Filter] Passing output 'com.google.Chrome' to Run Script
[11:42:24.841] Default Browser[Run Script] Processing complete
[11:42:24.847] Default Browser[Run Script] Passing output 'Browser '-frontend' is not installed. Options:
  org.torproject.torbrowser (Tor Browser)
  org.mozilla.firefox (Firefox)
  com.google.Chrome (Google Chrome)
  com.duckduckgo.macos.browser (DuckDuckGo)
  com.charliemonroe.Downie-4 (Downie 4)
* com.apple.Safari (Safari)' to Split Arg
[11:42:24.849] Default Browser[Split Arg] Processing complete
[11:42:24.850] Default Browser[Split Arg] Passing output 'Browser '-frontend' is not installed. Options:
  org.torproject.torbrowser (Tor Browser)
  org.mozilla.firefox (Firefox)
  com.google.Chrome (Google Chrome)
  com.duckduckgo.macos.browser (DuckDuckGo)
  com.charliemonroe.Downie-4 (Downie 4)
* com.apple.Safari (Safari)' to Conditional
[11:42:24.852] Default Browser[Conditional] Processing complete
[11:42:24.853] Default Browser[Conditional] Passing output 'Browser '-frontend' is not installed. Options:
  org.torproject.torbrowser (Tor Browser)
  org.mozilla.firefox (Firefox)
  com.google.Chrome (Google Chrome)
  com.duckduckgo.macos.browser (DuckDuckGo)
  com.charliemonroe.Downie-4 (Downie 4)
* com.apple.Safari (Safari)' to Debug
[11:42:24.854] Default Browser[Debug] 'Browser '-frontend' is not installed. Options:
  org.torproject.torbrowser (Tor Browser)
  org.mozilla.firefox (Firefox)
  com.google.Chrome (Google Chrome)
  com.duckduckgo.macos.browser (DuckDuckGo)
  com.charliemonroe.Downie-4 (Downie 4)
* com.apple.Safari (Safari)'
[11:42:24.855] Default Browser[Debug] Processing complete
[11:42:24.857] Default Browser[Debug] Passing output 'Browser '-frontend' is not installed. Options:
  org.torproject.torbrowser (Tor Browser)
  org.mozilla.firefox (Firefox)
  com.google.Chrome (Google Chrome)
  com.duckduckgo.macos.browser (DuckDuckGo)
  com.charliemonroe.Downie-4 (Downie 4)
* com.apple.Safari (Safari)' to Post Notification 

Posted (edited)

Hey @John Galvin

It doesn't look like you modified list.sh, since the bundle identifier is correctly passed to the Script Filter. 

 

22 hours ago, John Galvin said:

[11:42:23.819] Default Browser[Script Filter] Passing output 'com.google.Chrome' to Run Script

 

However, somehow "-frontend" ends up being passed into the script as bundle identifier.

This is puzzling at first, but I recall observing non-compiled, longer running swift scripts in the Activity Monitor being listed under the process name "swift-frontend".

 

I suspect this is related to the way the script is currently called within Alfred, i.e. to the input method of the Script Filter that uses /usr/bin/swift internally. Perhaps something is going wrong with the argument being passed when Alfred caches and handles the swift script.

 

Can you try this modified version of the workflow? 

https://transfer.archivete.am/ve9nv/Default Browser v1.3.2.alfredworkflow

 

@Andrew, depending on if this works for John, perhaps this is worth investigating as it might also be related to with this previous issue

 

The executable paths differ with each Script Filter input method and only the last method here has me take care of the input argument manually:

  • Language using internal /usr/bin/swift outputs ~/Library/Caches/com.runningwithcrayons.Alfred/Workflow Scripts/{{UUID}}
  • Language using External Script outputs ~/Library/Application Support/Alfred/Alfred.alfredpreferences/workflows/user.workflow.{{UUID}}/browser.swift  
  • Language using /bin/zsh --no-rcs outputs browser.swift when calling via swift browser.swift "$1"

 

 

Edited by zeitlings
Formatting
Posted

Still didn't work:

[13:23:25.459] Default Browser[Script Filter] Queuing argument '(null)'
[13:23:25.745] Default Browser[Script Filter] Script with argv '(null)' finished
[13:23:25.748] Default Browser[Script Filter] {
    "items": [
        {
            "title":"Safari",
            "arg":"com.apple.Safari",
            "icon":{
                "path":"icons/com.apple.Safari.png"
            }
        },{
            "title":"Chrome",
            "arg":"com.google.Chrome",
            "icon":{
                "path":"icons/com.google.Chrome.png"
            }
        },
    ]
}
[13:23:27.008] Default Browser[Script Filter] Processing complete
[13:23:27.013] Default Browser[Script Filter] Passing output 'com.google.Chrome' to Run Script
[13:23:28.378] ERROR: Default Browser[Run Script] ~
[DEBUG] Arguments:
 ~ [0]: </Library/Developer/CommandLineTools/usr/bin/swift-frontend>
 ~ [1]: <-frontend>
 ~ [2]: <-interpret>
 ~ [3]: <browser.swift>
 ~ [4]: <-enable-objc-interop>
 ~ [5]: <-stack-check>
 ~ [6]: <-sdk>
 ~ [7]: </Library/Developer/CommandLineTools/SDKs/MacOSX.sdk>
 ~ [8]: <-new-driver-path>
 ~ [9]: </Library/Developer/CommandLineTools/usr/bin/swift-driver>
 ~ [10]: <-empty-abi-descriptor>
 ~ [11]: <-resource-dir>
 ~ [12]: </Library/Developer/CommandLineTools/usr/lib/swift>
 ~ [13]: <-module-name>
 ~ [14]: <browser>
 ~ [15]: <-disable-clang-spi>
 ~ [16]: <-target-sdk-version>
 ~ [17]: <15.1>
 ~ [18]: <-target-sdk-name>
 ~ [19]: <macosx15.1>
 ~ [20]: <-external-plugin-path>
 ~ [21]: </Library/Developer/Developer/usr/lib/swift/host/plugins#/Library/Developer/Developer/usr/bin/swift-plugin-server>
 ~ [22]: <-external-plugin-path>
 ~ [23]: </Library/Developer/Developer/usr/local/lib/swift/host/plugins#/Library/Developer/Developer/usr/bin/swift-plugin-server>
 ~ [24]: <-plugin-path>
 ~ [25]: </Library/Developer/CommandLineTools/usr/lib/swift/host/plugins>
 ~ [26]: <-plugin-path>
 ~ [27]: </Library/Developer/CommandLineTools/usr/local/lib/swift/host/plugins>
 ~ [28]: <-->
 ~ [29]: <com.google.Chrome>
Browser "-frontend" is not installed.
=============================================
Eligible Applications:
   com.apple.Safari              |              Safari → /System/Volumes/Preboot/Cryptexes/App/System/Applications/Safari.app/
   org.mozilla.firefox           |             Firefox → /Applications/Firefox.app/
   com.charliemonroe.Downie-4    |            Downie 4 → /Applications/Downie 4.app/
   com.duckduckgo.macos.browser  |          DuckDuckGo → /Applications/DuckDuckGo.app/
   org.torproject.torbrowser     |         Tor Browser → /Applications/Tor Browser.app/
 * com.google.Chrome             |       Google Chrome → /Applications/Google Chrome.app/
   com.google.Chrome             |       Google Chrome → /var/folders/_4/225g83nx5hq7wlktwqk5j0pr0000gn/X/com.google.Chrome.code_sign_clone/code_sign_clone.StzTgQ/Google Chrome.app/
[13:23:28.398] Default Browser[Run Script] Processing complete
[13:23:28.399] Default Browser[Run Script] Passing output 'Browser "-frontend" is not installed.' to Split Arg
[13:23:28.401] Default Browser[Split Arg] Processing complete
[13:23:28.402] Default Browser[Split Arg] Passing output 'Browser "-frontend" is not installed.' to Conditional
[13:23:28.403] Default Browser[Conditional] Processing complete
[13:23:28.404] Default Browser[Conditional] Passing output 'Browser "-frontend" is not installed.' to Debug
[13:23:28.406] Default Browser[Debug] 'Browser "-frontend" is not installed.'
[13:23:28.407] Default Browser[Debug] Processing complete
[13:23:28.409] Default Browser[Debug] Passing output 'Browser "-frontend" is not installed.' to Post Notification

Posted (edited)

Interesting. The extra arguments you're seeing [0-27] are Swift compiler flags that are being exposed for some reason. When the script runs in Alfred, it appears to use swift-frontend directly on your end rather than the standard swift command wrapper, which is why you see all these internal compiler settings. 

 

To get the actual argument (com.google.chrome), we have to drop the compiler flags. With this change, the workflow should work for you: https://transfer.archivete.am/yUpB2/Default Browser v1.3.3.alfredworkflow

 

Please confirm if it does!

 

Edited by zeitlings
Posted

@zeitlings The workflow currently relies on a predetermined list of browsers that the user may or may not have installed, requiring manual updates and configuration to support new browsers. I noticed though that in your debugging code, you've already implemented the ability to automatically list eligible browsers.

 

Why not just format that to JSON in the Script Filter? Then you could do away with the long checkbox list in the Workflow Configuration and eliminate all the code for input validation, since the output would always be predictable and only ever include valid browsers. You probably wouldn't even need the extra Bundle ID File Action since everything would be automatic.

Posted
6 hours ago, FireFingers21 said:

Why not just format that to JSON in the Script Filter? Then you could do away with the long checkbox list in the Workflow Configuration and eliminate all the code for input validation, since the output would always be predictable and only ever include valid browsers. You probably wouldn't even need the extra Bundle ID File Action since everything would be automatic.

 

Fair point! Thanks for the suggestion. The workflow originally had an out-of-the-box list filter, thus the current structure. 

The only concern I might have is that not all "eligible applications", i.e. those that can handle http-URLs in some way, are actually browsers. For example, my list includes TeX Live UtilityDEVONagent, or even iTerm. I wouldn't want those to show up in the list. 

 

Though, perhaps a whitelist could still serve as gatekeeper and the File Action as a way to add more obscure browsers that are not yet whitelisted.

I'll consider it! However, refactoring/ improving the sdb workflow is currently low priority for me.

Posted
6 minutes ago, zeitlings said:

not all "eligible applications", i.e. those that can handle http-URLs in some way, are actually browsers

 

I've seen a few different sources that say adding an additional check for apps that handle HTML makes this a lot more reliable. This StackOverflow thread has a couple different suggestions: one using a deprecated LS function similar to what you use, and one using NSWorkspace from AppKit.

 

24 minutes ago, zeitlings said:

refactoring/ improving the sdb workflow is currently low priority for me

 

That's fair, I look forward to whatever you eventually decide to do!

Posted

Let me save you some trouble. I originally developed this for some Automation Tasks but ended up not using it. Wasn’t extensively tested but worked as desired in every situation I threw at it at the time.

 

import AppKit

// Get paths of installed browsers
func installedWebBrowsersURLs() -> Set<URL> {
  guard let httpsScheme: URL = URL(string: "https:") else { return [] }
  let htmlHandlerApps: [URL] = NSWorkspace.shared.urlsForApplications(toOpen: .html)
  let httpsHandlerApps: [URL] = NSWorkspace.shared.urlsForApplications(toOpen: httpsScheme)
  return Set(htmlHandlerApps).intersection(httpsHandlerApps)
}

// Get bundle IDs of installed browsers
func installedWebBrowsersBIDs() -> Set<String> {
  guard let httpsScheme: URL = URL(string: "https:") else { return [] }
  let htmlHandlerApps: [URL] = NSWorkspace.shared.urlsForApplications(toOpen: .html)
  let httpsHandlerApps: [URL] = NSWorkspace.shared.urlsForApplications(toOpen: httpsScheme)
  return Set(Set(htmlHandlerApps).intersection(httpsHandlerApps).compactMap { return Bundle(url: $0)?.bundleIdentifier })
}

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...