Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework protocol registration #1691

Merged
merged 7 commits into from
Jun 27, 2024
Merged

Rework protocol registration #1691

merged 7 commits into from
Jun 27, 2024

Conversation

erri120
Copy link
Member

@erri120 erri120 commented Jun 26, 2024

Resolves #1668.

  • reworked protocol registration on Linux and Windows
  • Sets the default on startup
  • Linux:
    • Create .desktop file and update MIME cache (we won't do this if the App has been installed with a package manager)
    • Uses xdg-settings to set default
  • Windows:
    • Sets the default handler using a generic ProgID, same as Vortex and MO2

@erri120 erri120 requested a review from a team June 26, 2024 13:11
@erri120 erri120 self-assigned this Jun 26, 2024
@Al12rs Al12rs self-requested a review June 26, 2024 13:39
@erri120
Copy link
Member Author

erri120 commented Jun 27, 2024

Notes on crappy Windows stuff:

Both Vortex and MO2 follow the documentation on Registering an Application to a URI Scheme.

This is done by updating the registry. Using HKEY_CURRENT_USER as the hive for user-specific stuff you create a sub-key at SOFTWARE\Classes\{protocol} like this:

HKEY_CURRENT_USER\SOFTWARE\Classes\nxm

Under this sub-key you set two values:

(Default) = "$NAME"
URL Protocol = ""

Followed by creating a sub-key at shell\open\command where the default value is the command to be executed with the link.

Vortex uses Electron's build-in function for this, while MO2 uses a custom function that does the same thing.

Since Vortex and MO2 write to the same keys, they are overwriting each other. These show the registry after Vortex ran, it updates these values on startup:

2024-06-27_12-36-37

2024-06-27_12-36-55

This has so far been on the OS level. If you open the Windows "Run" tool and try to run nxm://foo, the OS will start Vortex.

Browser abstract file associations one step further. Depending on the browser, you have something like this in your settings:

2024-06-27_12-38-50

If you then open a new tab and go to nxm://foo, the selected application will run. I think the browser also reads the same registry key to create this setting entry. If you choose "Always Ask", then you get this window when navigating to nxm://foo:

2024-06-27_12-42-03

All of this works fine if there is only every one application that makes use of this protocol. However, as well know, many mod managers exists and want to register themselves as a handler for nxm.

Vortex, MO2, and other tools use the same method, which is setting registry keys at SOFTWARE\Classes\nxm. In this context, nxm is referred to as a ProgID. It's a generic ProgID because it refers to the URI scheme.

For the longest time, Windows had support for selecting a "Default Program". Before Windows 10, this was done using the Control Panel, with Windows 10 and Windows 11 you have a new settings page called "Default Apps":

2024-06-27_12-47-32

This is the preferred way of setting default applications for both file and link types:

2024-06-27_12-49-56

This is described in the Default Programs documentation.

Vortex and MO2 don't show up here because they haven't registered themselves as an application to Windows. They used the very ancient method of registering a link handler.

Following the documentation and recommendations by Microsoft, we can add the Nexus Mods App to the "Default Apps" settings page on Windows:

2024-06-27_12-56-44

Doing the same things as before, "Run" and the Browser both recognize the App as a handler for nxm links and it just works ™️.

However, registration differs from what Vortex and MO2 do. Instead of using the generic ProgID nxm, we use an application-specific ProgID NexusMods.App.nxm. Since this is application-specific, other application won't be overwriting this in the registry:

2024-06-27_13-01-01

However, opening the "Default Apps" page on Windows after Vortex has updated the registry will get Windows confused:

2024-06-27_13-02-37

Because Vortex doesn't register itself as an application, the page says "NexusMods.App" but the URL:nxm is from Vortex. Vortex obviously also won't appear in the application list when setting a default app:

2024-06-27_13-03-21

Selecting "NexusMods.App" here will result in Vortex still being selected and appearing broken in the page. However, this is only appearances. If you run nxm://foo in Windows, it will still open the default, which is the App.

The same happens in the browser, it will only show "NexusMods.App" and use that. Since Vortex isn't a registered application, it won't show up anywhere. Not only that, Vortex and MO2 will never be able to register themselves as the default handler anymore.

Windows and Browsers will look for registered applications, if they can't find a registered application, they will default to the generic ProgID handler. If we register the App as an application, then it doesn't matter if Vortex or MO2 set a generic ProgID handler, it will never be used.

Summary

We can do two things:

  1. Follow Microsoft recommendations and register the App as an application to handle nxm links on Windows. This will use an application-specific ProgID like NexusMods.App.nxm.
  2. Use the generic ProgID nxm.

Option 1 is better integrated into the OS, but it will prevent Vortex and MO2 from ever being the default handler again, unless they also register themselves as an application. If they register themselves, then the user has the best experience since they can actually pick and choose in the OS and Browser.

Note that with Option 1, we won't be able to set ourselves as the default handler if there are multiple applications registered to handle nxm links. See this blog post for details.

Option 2 is the same method Vortex and MO2 use, and it's the "old" way of doing things. Going with this option means the App, Vortex, and MO2 fight for the same registry key, and setting a "default handler" is now up to the application. We'd need user interaction and settings to replicate the same things that Option 1 would give us, but instead of having the OS do all of this for us, we now need to implement user interactions ourselves. Specifically, we'd probably want to ask the user if we should be the default handler, or not.

@MattSturgeon
Copy link

However, registration differs from what Vortex and MO2 do.

Can this be mitigated by submitting PRs to vortex and mo2? Obviously that only affects future versions.

My instinct is that option 1 is better, but I feel like you'll also have to check the legacy registry key and (if it is set):

  • warn the user
  • ask if it should be reset

@Al12rs
Copy link
Contributor

Al12rs commented Jun 27, 2024

Option 1 would require changes to all other existing nxm protocol users, or risk preventing them from working.
Option 1 would not solve the problem of automatically dispatching based on which game the link is for.
Users would have to manually select the target when trying to mod with another manager.

I would go with Option 2 because it is the least likely to cause issues.

@Pickysaurus
Copy link
Contributor

My opinion as a Community Manager is to prefer Option 1. With the following rationale:

  • It's the expected pattern for Windows applications, we can consider the Option 2 method to be outdated and a bit of a hack. This also means Windows itself provides a UI for fixing protocol associations when registered this way - reducing the need for duplicate UIs to handle this in mod managers.
  • We can make this the standard approach and require NMM/MO2/Wabbajack/Vortex/M3Tweaks/ETBRocket to adopt this standard in order to remain a verified app. We should document exactly what we're doing and provide this to the application developers. The app will not see mass adoption for some time yet, so this is a good time to start rolling out this requirement slowly. I don't feel we should bind our hands because community tools are using Option 2. They can be given notice to update (and perhaps even help, as some of the most popular community tool authors work for Nexus Mods at present!)
  • Splitting downloads to different apps per game is still a separate problem. If we choose to tackle that in the app, create a standalone app for that specifically or rely on community-created tools for that (advanced) use case it can be considered separately.

@erri120
Copy link
Member Author

erri120 commented Jun 27, 2024

Splitting downloads to different apps per game is still a separate problem. If we choose to tackle that in the app, create a standalone app for that specifically or rely on community-created tools for that (advanced) use case it can be considered separately.

As a bonus to Option 1, if every application registers itself, this standalone app could automatically get a list of those applications instead of requiring the user to manually add each app with the correct arguments.

@Al12rs
Copy link
Contributor

Al12rs commented Jun 27, 2024

Lets assume, that Vortex and MO2 and App were all using Option1,
what would determine the selection?
Does the user get the question every time, or they choose the first time and then no option is presented?

Can applications change the default programmatically?

@erri120
Copy link
Member Author

erri120 commented Jun 27, 2024

Does the user get the question every time, or they choose the first time and then no option is presented?

If you run nxm://foo in the OS, then the OS App selector will pop-up if you haven't selected a default and have more than 2 registered applications for nxm links.

If you open a tab in your browser and go to nxm://foo, then the Browser settings take priority.

Can applications change the default programmatically?

The OS settings can't be changed automatically. UserChoice is protected, see this blog post for details.

I'm not sure about browser settings, but I don't think it's a great idea to muck with those. The user can just open the settings and change to "always use X" or "always ask".

@Sewer56
Copy link
Member

Sewer56 commented Jun 27, 2024

Option 1 would require changes to all other existing nxm protocol users, or risk preventing them from working. Option 1 would not solve the problem of automatically dispatching based on which game the link is for. Users would have to manually select the target when trying to mod with another manager.

I would go with Option 2 because it is the least likely to cause issues.

I've been trying to refrain from speaking on the topic yesterday, but my opinion here is the same in general.

The core issue is that at the end of the day, nxm is overloaded. It's a single protocol, but it should be pointing to multiple targets based on game support.

To that effect, we either could:

  • Add multiple buttons to the site, so that each manager gets its own sub-handler e.g. nxm-mo2. But this might clutter UI. Depends entirely on web devs, so unlikely to get done as there are more pressing matters.

  • Make a standard that all managers must implement, then any managers would have their own UI/UX to configure gamedomain->target associations. Actual dispatch logic could be shipped as library. Most flexibility for users, but probably too much UI work overall.

  • Make a standalone app that acts as a proxy, auto download it from supported managers and tell the users (or auto mark it if we can) as default handler. A good middle ground, wouldn't duplicate UI work.

I would go with Option 1 though if we can easily prompt the user to change the default (I.e. open settings in right page like browsers do). Because then the Proxy could auto-populate available managers because the handlers already specify how they wish for their programs to be invoked.

@Al12rs
Copy link
Contributor

Al12rs commented Jun 27, 2024

Can applications change the default programmatically?

The OS settings can't be changed automatically. UserChoice is protected, see this blog post for details.

I'm not sure about browser settings, but I don't think it's a great idea to muck with those. The user can just open the settings and change to "always use X" or "always ask".

Then I think this would strictly be a worse experience for end users, as with Option 2 you can switch handler by simply opening the application you wish to use before starting the download, while with Option 1 users would have to manually change the default application when wanting to switch to another game on another manager, or they would have to make the selection on every single link.

@Sewer56
Copy link
Member

Sewer56 commented Jun 27, 2024

I will also summarise what I've ranted about in Slack a while back.

A nxm proxy is not a wishlist item, I consider it a requirement as long as nxm is overloaded. There will always be games that will be supported by Vortex but not supported by NMA.

Likewise, we also have the policy where only Vortex supported games are allowed to have the nxm (Mod Manager Download) button. This will become a problem if NMA supports a game but Vortex does not, and vice versa.

Then there's also 3rd party Mod Managers, as this would allow them to better integrate with the site by supporting games 1st party ones might not. Instead of say, providing a worse UX and potentially losing games to competition. But I've been trying not to speak about that as the general attitude I've been receiving thus far is we should not care about anything that isn't 1st party and that it's their problem. I consider this train of thought unhealthy and generally against the spirit of modding which promotes user choice & freedom.

@erri120 erri120 requested a review from Al12rs June 27, 2024 14:12
@erri120 erri120 merged commit 5a582c9 into Nexus-Mods:main Jun 27, 2024
11 of 12 checks passed
@erri120 erri120 deleted the feat/1668 branch June 27, 2024 14:45
@MattSturgeon
Copy link

Splitting downloads to different apps per game is still a separate problem. If we choose to tackle that in the app, create a standalone app for that specifically or rely on community-created tools for that (advanced) use case it can be considered separately.

Make a standalone app that acts as a proxy, auto download it from supported managers and tell the users (or auto mark it if we can) as default handler. A good middle ground, wouldn't duplicate UI work.

I've seen (third-party) nxm proxy apps in the wild, since this is already a problem for users who have both mo2 and vortex installed.

Here's one example, and another.

the general attitude I've been receiving thus far is we should not care about anything that isn't 1st party and that it's their problem. I consider this train of thought unhealthy and generally against the spirit of modding which promotes user choice & freedom.

100% agree, that's a poor attitude. Though I do think you can still encourage best practices in third-party apps where appropriate, but you can't expect third-parties to always agree and/or have time to work on whatever it is.


IMO this is a good opportunity to encourage all nxm handling apps to start using the platform's best practices (option 1) rather than simply following suit and continuing to use the worse option.

@switch-blade-stuff
Copy link

IMO this is a good opportunity to encourage all nxm handling apps to start using the platform's best practices (option 1) rather than simply following suit and continuing to use the worse option.

As an end-user, I would generally prefer if things broke once to ensure a better experience down the line, rather than having to deal with an ever-increasing heap of patches to a subpar "legacy" solution that is likely to create conflicts and issues down the line either way.

Especially since, in my understanding, NMA is meant as a "next generation" mod manager for Nexus, and as such I wouldn't be opposed if it uses a new/updated protocol for handling Nexus mod links. Besides, NMA is still in it's early development stage, and I wouldn't expect many end users combining it with other mod managers.

Also wouldn't it be possible to use the "best practices new protocol" as the default while offering a compatibility fallback option in settings?

@Al12rs
Copy link
Contributor

Al12rs commented Jun 28, 2024

Option 1 for windows has been discarded for the following reasons:

  • The default app cannot be set programmatically, so if a user selects an option, it can't be overruled, unless the user goes in the windows settings (or browser in some cases) and manually changes the option.
  • Since the problem is that the App will initially only support a very small subset of games and users may want to use different managers for different games, this would actually make the end user experience much worse, as they would have to manually switch back and forth.

Option 1 is the Microsoft advised version, but it assumes something where the user will have a clear preference that does not need to change every time, e.g. what program to use to open PDF files.

NXM protocol has the problem that it is used for every Nexus game, but the reality is that users will likely have a different preferred application for different games, especially since the App and Vortex will coexist for a period as App builds up game support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Rework protocol registration on Linux
6 participants