will-stone / browserosaurus

🦖 The browser prompter for macOS
https://browserosaurus.com
GNU General Public License v3.0
1.74k stars 161 forks source link

Missing browsers in pop-up when clicking link #572

Closed mreid-tt closed 1 year ago

mreid-tt commented 2 years ago

Is there an existing issue for this?

Current Behaviour

Sometimes when I've started my machine, clicking a link does not show my complete list of browsers. Often times, my default browser would be missing and only a handful of the detected browsers would be displayed.

Expected Behaviour

All previously configured browsers would be shown in the pop-up when clicking a URL.

Steps To Reproduce

  1. Start iMac
  2. Open Notes or other text document
  3. Click URL link

Browserosaurus version

19.0.1

macOS version

12.6

CPU Architecture

ARM

Anything else?

This issue was previously happening in https://github.com/will-stone/browserosaurus/issues/462 but seems to have re-appeared as of version 19. For this occurrence, when I open the app's preference page it shows the correct count of apps but when I click on the apps tab not all the browsers are shown.

will-stone commented 2 years ago

Hi. Could you please share screenshots and/or videos, thanks 😊

will-stone commented 2 years ago

Oh, can you please upgrade to 19.1.0? Cheers.

mreid-tt commented 2 years ago

i didn't realise i wasn't on the latest version. i've upgraded and am now monitoring to see if the problem reoccurs. note that it did not happen on each boot of the iMac so i'll leave this open a while to see if it reoccurs.

mreid-tt commented 2 years ago

Unfortunately it's still happening...

https://user-images.githubusercontent.com/943378/192991625-d2572eee-00aa-472c-8647-c7fa9638ada6.mov

Screenshot 2022-09-29 at 5 13 28 AM
will-stone commented 2 years ago

Could you please try running the Factory Reset? As it might be a corrupt store. Thanks

mreid-tt commented 2 years ago

okay, so i've done a factory reset and it was working well but today i saw my default browser missing from the list...

https://user-images.githubusercontent.com/943378/193431674-a94f78f7-d2bf-4e3d-839e-a5c0a9a5fbbe.mov

will-stone commented 2 years ago

Very strange. It's odd it's only not picking up Brave. Let's see if anyone else reports something similar so we can find a pattern.

mreid-tt commented 2 years ago

The issue is not only with Brave. There is a random number of browsers it will pick up just like in the original ticket https://github.com/will-stone/browserosaurus/issues/462 I opened for this. Here's it today only picking up one...

https://user-images.githubusercontent.com/943378/193468312-fb1597a5-85a2-4bbd-9aaa-7e8339ed0436.mov

mrplug commented 2 years ago

Hello all,

I can confirm the error. For me, the scan finds 9 browsers, but only 8 are displayed in the list. Safari is always missing for me. Even hitting the rescan button multiple times does not fix it. It is like i have to open the option menu and wait a specific time to refresh.

I have also tried resetting to factory settings. Unfortunately, it did not help. The error occurs again after every restart.

macOS version 13.0

CPU Architecture x86/x64

will-stone commented 2 years ago

Thanks @mrplug These intermittent bugs are a pain! Have you had a chance to look at the code? Happy to review a PR 😊

tomsamwel commented 2 years ago

Mine stopped picking up Brave today. Rescan, factory reset and reinstallation did not help.

lkravchuk commented 2 years ago

I have exactly the same issue on macOS 13.0 (Intel), every time I restart MacBook, Safari disappears from the list. Gladly, rescan helps, but I have to run it after every restart. No issues with the other apps (Figma, Slack, Vivaldi, Chrome)

stefanschwartzjnr commented 2 years ago

Same issue here on macOS Ventura (Intel). Safari is my default browser, and after restart I have to rescan apps and then everything is okay.

mreid-tt commented 2 years ago

@will-stone I know when you resolved this back in 16.1.0, you mention in the release notes:

To speed-up first load, the scan for apps is now delayed until first open of either picker or preferences windows. This will also give Spotlight a chance to load its index if you have B to start on login.

Did you take a look at this fix again to see if there is need to alter the delay in the scan for apps? Hoping that it can be a quick fix for the current version.

EDIT: This issue is also still happening for me on B v19.1.0 on macOS v13.0.1 (ARM)

will-stone commented 2 years ago

There's no more delay it just keeps retrying every half second until at least one app is found. It could be changed to keep going until at least Safari is found. Please submit a PR and I'll gladly take a look.

mreid-tt commented 2 years ago

Unfortunately I am not familiar enough with your codebase structure to suggest a PR that would make sense. I am also not that versed in TypeScript. In any event, I believe the current logic presumes that when one app is found that all apps should be visible and this is not the case in practice.

What we could possibly do is leverage the value on the main screen which lists the correct number of apps previously stored. Then for the line: https://github.com/will-stone/browserosaurus/blob/f8eaf15814e278226cf357966065f4002da3e286/src/main/utils/get-installed-app-ids.ts#L16 We could replace it with logic more like:

if (installedApps.length !== storedNumberOfApps) {

That way, it will wait until it has found the number of apps previously detected (I don't know how to reference the real variable for storedNumberOfApps). What do you think?

will-stone commented 2 years ago

What happens if an app has been removed since last scan/boot? Wouldn’t you then be stuck in an infinite loop?

mreid-tt commented 2 years ago

What happens if an app has been removed since last scan/boot? Wouldn’t you then be stuck in an infinite loop?

This is true. I guess we can put this into a counter which would limit the number of times it would loop.

mreid-tt commented 2 years ago

@will-stone, so I tried to do a deep dive into the code to better understand how it works (though I am not that versed in TypeScript). The codebase is somewhat difficult to grasp since there are so many dependencies and the logic is often not clear (with very few comments if any).

What I could glean is that:

  1. This line calls for a search of apps in the system based on a list of approved apps https://github.com/will-stone/browserosaurus/blob/472bda1b3fc2a85194092bf12fa2e57526570511/src/main/utils/get-installed-app-ids.ts#L20
  2. The list of approved apps seems to be in this file
  3. The actual search is handed off to another library which executes a search using this code

    const {stdout: appPath} = await execFileP('mdfind', [query, ...pathArgs]);

  4. This code returns the path of each approved app by searching the bundle identifiers in the list

A few questions/observations:

  1. The function getInstalledAppIds() seems to call itself if installedApps.length === 0. Would the possibility of multiple recursive calls be a performance concern when the app is just launching on boot?

  2. With the list of approved apps now including over 60 app bundle identifiers, could this many parallel searches be slowing down the spotlight search results?

    I acknowledge the challenges in identifying if the spotlight index is fully available since there is no parameter within mdutil to know if the index is ready for searching. This can result in searches for a particular file yielding no resultant path. I have seen this myself by running the following command within a minute of bootup mdfind "kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'com.brave.Browser'"

  3. Could an alternate approach be taken to search for all apps in the /Applications and ~/Applications folders and then match them with the extracted bundle identifiers?

    For example, this command seems to give me all the apps in the main apps folder mdfind -onlyin "/Applications" "kMDItemKind == 'Application'". I would expect that this list would be either empty or complete when returned versus the partial results which are returned by searching for each approved app individually. Now each app in the result would then need to be checked for the app bundle identifier which can be slow (for example as a single command this would be mdfind -onlyin "/Applications" "kMDItemKind == 'Application'" | while read -d $'\n' file; do printf "%s\n" $(mdls -name kMDItemCFBundleIdentifier -raw "$file"); done). My question is, would it be that much slower? Would the potential improvement in the reliability of the results be a reasonable tradeoff?

Interested to hear your thoughts on the above analysis and proposal.

EDIT: Fixed the text I meant to indent which previously looked like quotes.

will-stone commented 2 years ago

Hi @mreid-tt Thanks for writing up your understanding. Let's address each question:

  1. The recursion is throttled by the wait line above it. This recursion is what mitigates the case of the Spotlight index not being ready.
  2. Yes, this has always been a worry of mine. I have been hoping to find an OS API that could detect installed browsers but have not had any luck so far. Please note, the code in Sindre's repository was written by myself; I was using that method and noticed he had a project dedicated for checking for the existence of an app, so thought it best if the logic lived there for all to use.
  3. I like this, in theory. However, one downside to this approach is that not everyone stores their apps in these places. Also, is the folder called "Applications" in all languages?
will-stone commented 2 years ago

Ooo, one thing we could do (inspired by your run-mdfind-once method) is search for all apps at once, e.g.

mdfind "kMDItemCFBundleIdentifier==org.mozilla.firefox || kMDItemCFBundleIdentifier==com.apple.Safari || kMDItemCFBundleIdentifier==com.pushplaylabs.sidekick || ..."

I'm not sure how to interpret the results yet but this may be a good place to start.

mreid-tt commented 2 years ago

Thanks much for confirming my understanding of the logic. To continue the discussion:

However, one downside to this approach is that not everyone stores their apps in these places. Also, is the folder called "Applications" in all languages?

Based on the research I did, the actual path does not change based on localisation (see Programmatically get the name of the Application Folder in OSX and Languages and file paths). As for persons storing apps outside of /Applications and ~/Applications, I'm not sure what we can do about that since the OS really expects apps to be stored there.

I have been hoping to find an OS API that could detect installed browsers but have not had any luck so far.

This is indeed a preferred approach. I don't know if you've already seen this thread: Enumerating installed browsers on OS X. This then led me to search on the LSCopyApplicationURLsForURL function which is also mentioned in this thread: List ALL applications associated with file?. I then landed on the function URLsForApplicationsToOpenURL because the former seems to be deprecated.

Now to be honest a lot of this is over my head but I thought it might be useful to assist with answering your original research question.

Ooo, one thing we could do (inspired by your run-mdfind-once method) is search for all apps at once

Hmm, interesting... but you are right, there is no way to reliably match the file paths returned with the known bundle identifiers in a batch query like this. I would really prefer my proposal since from the little testing I did, if you look for all the apps just after boot, it returns a complete list and doesn't give a partial result. From there we can extract bundle identifiers reliably for each path returned to match against the internal list.

will-stone commented 2 years ago

But then wouldn’t we be running more mdfinds? One for each installed app?

mreid-tt commented 2 years ago

But then wouldn’t we be running more mdfinds? One for each installed app?

Yes, you are correct that there would be multiple calls to mdls (not mdfind), which is why I posed this question at the end of the proposal:

My question is, would it be that much slower? Would the potential improvement in the reliability of the results be a reasonable tradeoff?

Here's my reasoning behind the proposed solution:

  1. At present B has an internal list of 60+ apps. Each of these require a call to mdfind and depending on the state of the Spotlight index the results may be unreliable
  2. Based on limited testing, the result of getting a list of all apps in the standard locations is very reliable
  3. Checking the bundle identifiers for the apps returned would be less calls overall because based on a Mac Apps Report 2021, the average number of apps installed across the surveyed users was 31. As such, barring extreme cases, this would seem like the more efficient option

Let me know what you think.

will-stone commented 2 years ago

ah, it's because you're using quotes to make statements: I keep skipping them, thinking you're quoting me 🙂

Sounds great. I'll look into it 👍

will-stone commented 2 years ago

I've just installed Brave and had the same issue, where it wasn't picking it up. But it wasn't listed in mdfind kMDItemKind == 'Application' -onlyin '/Applications' until I deselected Applications and reselected it in Spotlight settings. So... unfortunately it's nothing to do with B, it's a Ventura bug.

@mreid-tt I've changed the logic for finding apps which makes it faster and more scalable, but as mentioned above, it will not solve the issues people are having as mdfind is driven by the Spotlight index and if this isn't working, there's nothing I can do 😞 New logic can be seen here and will be in next release.

mreid-tt commented 2 years ago

Hey, thanks very much for considering my proposal. From what you shared it appears that finding all matching applications at once is not always reliable as it initially appeared to be. I look forward to the next release and perhaps we can see if it changes the intermittency of the symptoms in any way.

I don't know if you had any time to look into these results I shared earlier. Do you think they could help?

I don't know if you've already seen this thread: Enumerating installed browsers on OS X. This then led me to search on the LSCopyApplicationURLsForURL function which is also mentioned in this thread: List ALL applications associated with file?. I then landed on the function URLsForApplicationsToOpenURL because the former seems to be deprecated.

EDIT: I've installed version 19.3.2 but I still see some missing browsers from time to time. This time I have to refresh it more times to get a complete list. I don't know if this makes it less reliable for persons in the community. Interested to hear feedback from others.

Sebi11 commented 2 years ago

Same issue here since this morning when I installed version 19.3.2. I'm missing Chrome and Edge from the list, despite running a "rescan" and resetting the preferences 🤔

salimhb commented 2 years ago

I'm having a similar issue. At first only Safari was missing. When I reset the app, most Browsers were missing and only Apps (Figma, Miro, ...) were shown. Now FF/Brave/Chrome/Safari TP are back. Only Safari is still missing. Is it possible because I have the Safari Technology Preview?

will-stone commented 2 years ago

:rotating_light: This is not Browserosaurus: Spotlight is not properly indexing your applications :rotating_light:

Uncheck Applications in Spotlight and check it again. Then wait a min, then restart Browserosaurus.

image
Sebi11 commented 2 years ago

I tried that @will-stone but I'm still missing one browser (randomly it seems).

salimhb commented 2 years ago

Thanks @will-stone, this helps a bit, but now I have Safari again and Firefox is gone 😅 If there's anything I can send you to help troubleshoot this issue?

mreid-tt commented 2 years ago

Hey @will-stone, it does appear that finding all apps for the initial search is proving equally unreliable given the feedback and my own experiences. Might I propose the following amendment:

  1. Given that we are starting with a list of all apps, why don't we simply get a list using find? I did some tests and we can replicate the output from mdfind -onlyin /Applications -onlyin ~/Applications "kMDItemKind == 'Application'" with something like find ~/Applications /Applications -iname "*.app" -maxdepth 1
  2. The next steps for the calling of mdls should look exactly the same. In my tests I was able to combine as a single command: find ~/Applications /Applications -iname '*.app' -maxdepth 1 | while read -d $'\n' file; do printf "%s\n" $(mdls -name kMDItemCFBundleIdentifier -raw "$file"); done

I am hopeful that if we move away from mdfind altogether we can probably solve the reliability issue.

EDIT: I've created a PR to implement the above: https://github.com/will-stone/browserosaurus/pull/587

iamsoum commented 2 years ago

Just popping in here to say that I'm facing the same issue. Good to know it's happening to many people (not intended to say the issue is good but I mean I'm relieved I'm not alone)

Upon scanning it detected 11 apps (it's not able to scan Firefox because in reality it should show 12 apps) but in reality it only shows 7 apps. I did factory reset. Nothing happened. Then I unchecked applications in Spotlight. Now it shows only 6 apps scanned. It's unable to scan for more apps.

Interesting thing to note is that this is happening on my new M2 MacBook Air. Earlier it was working fine on my intel Mac.

will-stone commented 2 years ago

You have to make sure you check “applications” again as it really won’t work.

No more “me too”s please 🙏 A solution is being worked on but we still may be at the mercy of Apple here.

If someone would really like to help out: please try to isolate the issue with mdfind/mdls and report it to Apple. Thank you.

Maddog2050 commented 2 years ago

I'm seeing this issue also, but after doing some digging it seems to be an issue with mdfind metadata because if you specify the query "kMDItemKind == 'Application'" the output is missing applications but if you specify the query as "kMDItemKind == *" all applications are listed. As you can see from the two outputs below there are 2 applications missing (Brave Browser and Browserosaurus) even though there kMDItemKind is Application.

Rebuilding the metadata stores using sudo mdutil -E / has fixed the issue for me.

# mdfind "kMDItemKind == 'Application'" -onlyin /Applications -onlyin /Users/user/Applications -attr kMDItemKind
/Applications/1Password for Safari.app   kMDItemKind = Application
/Applications/1Password.app   kMDItemKind = Application
/Applications/Adobe Acrobat Reader.app   kMDItemKind = Application
/Applications/Amazon Chime.app   kMDItemKind = Application
/Applications/Amphetamine.app   kMDItemKind = Application
/Applications/Company Portal.app   kMDItemKind = Application
/Applications/Cyberduck.app   kMDItemKind = Application
/Applications/DBeaver.app   kMDItemKind = Application
/Applications/DiffusionBee.app   kMDItemKind = Application
/Applications/Docker.app   kMDItemKind = Application
/Applications/Falcon.app   kMDItemKind = Application
/Applications/FortiClient.app   kMDItemKind = Application
/Applications/FortiClientUninstaller.app   kMDItemKind = Application
/Applications/GIMP-2.10.app   kMDItemKind = Application
/Applications/Google Chrome.app   kMDItemKind = Application
/Applications/Keka.app   kMDItemKind = Application
/Applications/Lens.app   kMDItemKind = Application
/Applications/Microsoft Excel.app   kMDItemKind = Application
/Applications/Microsoft OneNote.app   kMDItemKind = Application
/Applications/Microsoft Outlook.app   kMDItemKind = Application
/Applications/Microsoft PowerPoint.app   kMDItemKind = Application
/Applications/Microsoft Teams.app   kMDItemKind = Application
/Applications/Microsoft Word.app   kMDItemKind = Application
/Applications/OneDrive.app   kMDItemKind = Application
/Applications/OpenLens.app   kMDItemKind = Application
/Applications/Parallels Desktop.app   kMDItemKind = Application
/Applications/Parallels Desktop.app/Contents/Applications/Parallels Link.app   kMDItemKind = Application
/Applications/Parallels Desktop.app/Contents/Applications/Parallels Mounter.app   kMDItemKind = Application
/Applications/Parallels Desktop.app/Contents/Applications/Parallels Technical Data Reporter.app   kMDItemKind = Application
/Applications/Rectangle.app   kMDItemKind = Application
/Applications/Remote Desktop Manager Free.app   kMDItemKind = Application
/Applications/Safari.app   kMDItemKind = Application
/Applications/Shottr.app   kMDItemKind = Application
/Applications/Sublime Text.app   kMDItemKind = Application
/Applications/TeamViewerHost.app   kMDItemKind = Application
/Applications/Visual Studio Code.app   kMDItemKind = Application
/Applications/Warp.app   kMDItemKind = Application
/Applications/Wireshark.app   kMDItemKind = Application
/Applications/draw.io.app   kMDItemKind = Application
/Applications/iTerm.app   kMDItemKind = Application
/Applications/p4admin.app   kMDItemKind = Application
/Applications/p4merge.app   kMDItemKind = Application
/Applications/p4v.app   kMDItemKind = Application
/Applications/zoom.us.app   kMDItemKind = Application
mdfind "kMDItemKind == *" -onlyin /Applications -onlyin /Users/user/Applications -attr kMDItemKind
/Applications/1Password for Safari.app   kMDItemKind = Application
/Applications/1Password.app   kMDItemKind = Application
/Applications/Adobe Acrobat Reader.app   kMDItemKind = Application
/Applications/Amazon Chime.app   kMDItemKind = Application
/Applications/Amphetamine.app   kMDItemKind = Application
/Applications/Brave Browser.app   kMDItemKind = Application
/Applications/Browserosaurus.app   kMDItemKind = Application
/Applications/Company Portal.app   kMDItemKind = Application
/Applications/Cyberduck.app   kMDItemKind = Application
/Applications/DBeaver.app   kMDItemKind = Application
/Applications/DiffusionBee.app   kMDItemKind = Application
/Applications/Docker.app   kMDItemKind = Application
/Applications/Falcon.app   kMDItemKind = Application
/Applications/FortiClient.app   kMDItemKind = Application
/Applications/FortiClientUninstaller.app   kMDItemKind = Application
/Applications/GIMP-2.10.app   kMDItemKind = Application
/Applications/Google Chrome.app   kMDItemKind = Application
/Applications/Keka.app   kMDItemKind = Application
/Applications/Lens.app   kMDItemKind = Application
/Applications/Microsoft Excel.app   kMDItemKind = Application
/Applications/Microsoft OneNote.app   kMDItemKind = Application
/Applications/Microsoft Outlook.app   kMDItemKind = Application
/Applications/Microsoft PowerPoint.app   kMDItemKind = Application
/Applications/Microsoft Teams.app   kMDItemKind = Application
/Applications/Microsoft Word.app   kMDItemKind = Application
/Applications/OneDrive.app   kMDItemKind = Application
/Applications/OpenLens.app   kMDItemKind = Application
/Applications/Parallels Desktop.app   kMDItemKind = Application
/Applications/Parallels Desktop.app/Contents/Applications/Parallels Link.app   kMDItemKind = Application
/Applications/Parallels Desktop.app/Contents/Applications/Parallels Mounter.app   kMDItemKind = Application
/Applications/Parallels Desktop.app/Contents/Applications/Parallels Technical Data Reporter.app   kMDItemKind = Application
/Applications/Rectangle.app   kMDItemKind = Application
/Applications/Remote Desktop Manager Free.app   kMDItemKind = Application
/Applications/Safari.app   kMDItemKind = Application
/Applications/Shottr.app   kMDItemKind = Application
/Applications/Sublime Text.app   kMDItemKind = Application
/Applications/TeamViewerHost.app   kMDItemKind = Application
/Applications/Utilities   kMDItemKind = Folder
/Applications/Visual Studio Code.app   kMDItemKind = Application
/Applications/Warp.app   kMDItemKind = Application
/Applications/Wireshark.app   kMDItemKind = Application
/Applications/draw.io.app   kMDItemKind = Application
/Applications/iTerm.app   kMDItemKind = Application
/Applications/p4admin.app   kMDItemKind = Application
/Applications/p4merge.app   kMDItemKind = Application
/Applications/p4v.app   kMDItemKind = Application
/Applications/zoom.us.app   kMDItemKind = Application
fabiostawinski commented 2 years ago

For me it is the same, started appearing only chrome, after I the factory reset, now it doesnt' show chrome anymore. I used brew to install it, is there any difference it I clone the code and install manually?

will-stone commented 2 years ago

Thanks @mreid-tt for all the help so far. Please try 19.3.3 and let me know if it works. It doesn't go as far as @mreid-tt's suggestions but let's see how it goes 🙂

mreid-tt commented 2 years ago

Thanks @mreid-tt for all the help so far. Please try 19.3.3 and let me know if it works. It doesn't go as far as @mreid-tt's suggestions but let's see how it goes 🙂

So it is a much simpler fix to improve the browser list reliability. Overall there should be far fewer function calls so there would be an efficiency improvement as well in the scanning. As noted in the discussion on my PR, the list is generally complete via this approach when run within one minute of boot with the exception of Safari. I have to do a manual rescan after about another minute or two have passed for it to be re-added to the list.

mreid-tt commented 1 year ago

This issue appears to be addressed with https://github.com/will-stone/browserosaurus/pull/593. As such I will be closing it.