gluon icon indicating copy to clipboard operation
gluon copied to clipboard

Use user-preferred browser by default

Open ThaUnknown opened this issue 2 years ago • 12 comments

Currently gluton hardcodes a few browsers, however is someone is using a different browser like for example a custom chromium build or browsers like opera or brave this fails.

A decent solution would be:

  • use the system preferred browser
    • windows:
      • HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\URLAssociations\https\UserChoice
      • ProgID - REG_SZ
      • HKEY_LOCAL_MACHINE\SOFTWARE\Classes\${ProgID}\shell\open\command
      • (Default) - REG_SZ
    • linux: ???
    • macOS: ???
  • get all available browsers for the OS
    • ??

for windows the best module for navigating regedit seems to be winreg, not sure how to do this on linux/macos

ThaUnknown avatar Jan 02 '23 01:01 ThaUnknown

Would be cool, currently is just in order of most preferred/usable by Gluon. Would likely use reg.exe directly to avoid external dependencies.

CanadaHonk avatar Jan 02 '23 01:01 CanadaHonk

Would be cool, currently is just in order of most preferred/usable by Gluon. Would likely use reg.exe directly to avoid external dependencies.

winreg doesnt have any external dependencies, so I think it's a safe go, it's also been stable for a few years

ThaUnknown avatar Jan 02 '23 01:01 ThaUnknown

I meant having a dependency at all, as you can make a wrapper for reg.exe in ~5 lines

CanadaHonk avatar Jan 02 '23 01:01 CanadaHonk

I meant having a dependency at all, as you can make a wrapper for reg.exe in ~5 lines

hm, too bad, wanted to PR this using that lib, but making a wrapper for a windows executable and parsing errors isn't my forte, here's the code using winreg, util.promisify doesn't seem to work on it :/

import Registry from 'winreg'

const preferred = new Registry({
  hive: Registry.HKCU,
  key: '\\SOFTWARE\\Microsoft\\Windows\\Shell\\Associations\\URLAssociations\\https\\UserChoice'
})
preferred.get('ProgID', (_err, item) => {
  const ProgID = item.value
  const browser = new Registry({
    hive: Registry.HKLM,
    key: `\\SOFTWARE\\Classes\\${ProgID}\\shell\\open\\command`
  })
  browser.get(Registry.DEFAULT_VALUE, (_err, item) => {
    const shell = item.value
    console.log(shell)
  })
})

ThaUnknown avatar Jan 02 '23 02:01 ThaUnknown

Oh, apologies. Code looks good and understandable, using a custom wrapper allows using promises as well so lol.

CanadaHonk avatar Jan 02 '23 02:01 CanadaHonk

Possibly could be an easier idea to use file associations like .html instead. Dedicated command line tool for it on Windows so would be much simpler but unsure if some people/browsers don't set file associations.

CanadaHonk avatar Jan 02 '23 02:01 CanadaHonk

Preferred file associations for .html would be a generally safe bet, but accessing based on https preferences may be the best way to go? Windows is a "little" aggressive with their promotion of Microsoft Edge, so they don't reliably change all file types when you update your preferences.

steviegt6 avatar Jan 03 '23 12:01 steviegt6

Preferred file associations for .html would be a generally safe bet, but accessing based on https preferences may be the best way to go? Windows is a "little" aggressive with their promotion of Microsoft Edge, so they don't reliably change all file types when you update your preferences.

.html is bad as it also lists text editors like vscode which are also in theory chromium, so i just went with https and browser detection

ThaUnknown avatar Jan 03 '23 12:01 ThaUnknown

Yeah changed my mind, have an almost complete implementation which I'm leaving for 0.10.0, 0.9.0 should be releasing today with some new APIs.

CanadaHonk avatar Jan 03 '23 12:01 CanadaHonk

On macOS I have found a way to obtain the default browser.

You can use plutil -convert json -o - ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist to obtain the mapping of schemes/protocols to bundle IDs. [^1] [^2]

From that, you get something like:

{
  "LSHandlers" : [
    { /* Other options */ }
    {
      "LSHandlerPreferredVersions" : {
        "LSHandlerRoleAll" : "-"
      },
      "LSHandlerRoleAll" : "org.mozilla.firefox",
      "LSHandlerURLScheme" : "https"
    },
    { /* Other options */ }
  ]
}

Parsing that JSON, you can search for the object whose property LSHandlerURLScheme equals "https" and obtain the value of the property LSHandlerRoleAll, which is the bundle identifier of the application -- in this case "org.mozilla.firefox".

Then, you can use mdfind kMDItemCFBundleIdentifier = "org.mozilla.firefox", which will return the path of the application that that identifier belongs to. In this case, for my setup, it returned /Applications/Firefox.app.

From this information, you can access the Info.plist, which is located in /Applications/Firefox.app/Contents/Info.plist and once again use plutil to fetch the executable file that should be run using plutil -extract CFBundleExecutable raw /Applications/Firefox.app/Contents/Info.plist.

This will return firefox, which means the final path is /Applications/Firefox.app/Contents/MacOS/firefox.

You can also use plutil -extract CFBundleName raw /Applications/Firefox.app/Contents/Info.plist to obtain the application name, which will return "Firefox" for Firefox and "Chrome" for Google Chrome. This can be useful to compare against the supported browsers for gluon.

[^1]: Taken from here. Note that the path differs for older versions of macOS. [^2]: You can add the -r to get a prettified JSON response.

bernardobelchior avatar Jan 20 '23 19:01 bernardobelchior

On Windows getting exe path from this is most universal: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\${ProgID}\shell\open\command. It will also work when users have non-standard path. Which would be more common for Firefox then Chrome probably.

Eccenux avatar Jan 29 '23 21:01 Eccenux

On Windows getting exe path from this is most universal: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\${ProgID}\shell\open\command. It will also work when users have non-standard path. Which would be more common for Firefox then Chrome probably.

image its legit in the original post

ThaUnknown avatar Jan 29 '23 21:01 ThaUnknown