Repository: electron/electron (language: cpp)

Issue:
Wrong web browser opened when clicking links
### Preflight Checklist

- [x] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [x] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [x] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success.

### Electron Version

33.3.0

### What operating system(s) are you using?

Ubuntu

### Operating System Version

24.04

### What arch are you using?

x64

### Last Known Working Electron version

_No response_

### Expected Behavior

Links open in the configured default browser

### Actual Behavior

Links open in Chrome/Chromium instead, regardless of the configured default browser

### Testcase Gist URL

https://gist.github.com/Viicos/d77af018be1b7b27294a74c378731992

### Additional Information

This is a re-open of https://github.com/electron/electron/issues/42611 (by @bittylicious) after @viicos was so kind to add a repro gist (adding a gist was an absolute requirement by the Electron team on the original issue).

The original issue already well pointed out that this issue seems to be new with Ubuntu 24 and wasn't present on 22.

Workarounds presented in in the original issue:

* Uninstalling all chrome/chromium (then e.g. a firefox will be correctly opened)
* Adding the following to `~/.local/share/applications/mimeapps.list`

```
[Default Applications]
x-scheme-handler/http=firefox_firefox.desktop
x-scheme-handler/https=firefox_firefox.desktop
```

There are some additional details available in the original issue.


Discussion / hints:
As I mentioned in the closed issue, the provided gist produced the expected behavior on Windows, so this is most likely a Linux only issue.
@mlaurencin that's how it was triaged from the get-go, what made an inability to repro in Windows appropriate to close the issue?

![Image](https://github.com/user-attachments/assets/6b61add7-967e-4a12-9763-104b58ca60b3)

> what made an inability to repro in Windows appropriate to close the issue?

This wasn't the reason the original issue was closed, but rather because it was missing a simple reproducible example (as mentioned [here](https://github.com/electron/electron/issues/42611#issuecomment-2195677650)).
Thank you for doing this @NobodysNightmare @Viicos .

This is just a grumbling response as it would have affected **everybody** who uses Firefox as their default browser, on the latest stable Ubuntu, yet the original issue was closed even though it is easy to reproduce. This must affect thousands of people and likely lose Firefox a lot of "default browser" settings, which sucks when Chrome has such market share.
I faced the same with web links but also when opening PDF files from the desktop client of @tutao based on Electron. The PDF files were opened by calibre (ebook reader) instead of evince pdf reader whereas evince is set as the default pdf reader...

Same workaround, adding this to `~/.local/share/applications/mimeapps.list`:
```
application/pdf=org.gnome.Evince.desktop
application/x-bzpdf=org.gnome.Evince.desktop
application/x-ext-pdf=org.gnome.Evince.desktop
application/x-gzpdf=org.gnome.Evince.desktop
application/x-xzpdf=org.gnome.Evince.desktop
```

If someone face the same issue with other files, you can look in `/usr/share/applications/gnome-mimeapps.list` for references with mime types.

Clicking on links has the expected behavior on other apps which are not based on Electron (pdf reader, other e-mail clients, text editor, etc.) so it looks related to Electron and not Ubuntu.
I did some digging into this, I believe the cause for this is that Electron sets the `XDG_CURRENT_DESKTOP` environment variable to `Unity` for Linux systems. They preserve the original value in `ORIGINAL_XDG_CURRENT_DESKTOP`. I've tested and confirmed that restoring the original value before calling `electron.shell.openExternal` makes it honor the system defaults.

This gets a [very brief callout in the Electron docs](https://www.electronjs.org/docs/latest/api/environment-variables#original_xdg_current_desktop). They claim this is to improve Chromium compatibility and I have no reason to doubt that, but it seems like a bug/unexpected behavior for `electron.shell.openExternal` and `electron.shell.openPath` to not honor the original value.

I'm admittedly a noob in the Electron codebase and it's been forever since I've touched C++, but it seems like the overridden `XDG_CURRENT_DESKTOP` env var is used elsewhere in Chromium so it needs to be preserved, but `shell/common/platform_util_linux.cc` is not dependent on it. It seems like the `XDGUtil` function in `shell/common/platform_util_linux.cc` is the right place to correct this, as it seems like all the functions that call this are ones that should honor the system default. I think the following should work for overriding the original value, but I'm curious to get input from an Electron maintainer. @mlaurencin @clavin 

```diff
diff --git a/shell/common/platform_util_linux.cc b/shell/common/platform_util_linux.cc
index 125b4d037a..0efd462e06 100644
--- a/shell/common/platform_util_linux.cc
+++ b/shell/common/platform_util_linux.cc
@@ -58,6 +58,9 @@ const char kFreedesktopPortalName[] = "org.freedesktop.portal.Desktop";
 const char kFreedesktopPortalPath[] = "/org/freedesktop/portal/desktop";
 const char kFreedesktopPortalOpenURI[] = "org.freedesktop.portal.OpenURI";
 
+const char kXdgCurrentDesktopEnvVar[] = "XDG_CURRENT_DESKTOP";
+const char kOriginalXdgCurrentDesktopEnvVar[] = "ORIGINAL_XDG_CURRENT_DESKTOP";
+
 const char kMethodOpenDirectory[] = "OpenDirectory";
 
 class ShowItemHelper {
@@ -282,6 +285,11 @@ bool XDGUtil(const std::vector<std::string>& argv,
     base::nix::CreateLaunchOptionsWithXdgActivation(base::BindOnce(
         [](base::RepeatingClosure quit_loop, base::LaunchOptions* options_out,
            base::LaunchOptions options) {
+          if (options.environment.find(kOriginalXdgCurrentDesktopEnvVar) !=
+              options.environment.end()) {
+              options.environment[kXdgCurrentDesktopEnvVar] =
+                options.environment[kOriginalXdgCurrentDesktopEnvVar];
+          }
           *options_out = std::move(options);
           std::move(quit_loop).Run();
         },
```

Fix patch:
diff --git a/shell/common/platform_util_linux.cc b/shell/common/platform_util_linux.cc
index 125b4d037a474..9dd491945548f 100644
--- a/shell/common/platform_util_linux.cc
+++ b/shell/common/platform_util_linux.cc
@@ -15,6 +15,7 @@
 
 #include "base/cancelable_callback.h"
 #include "base/containers/contains.h"
+#include "base/containers/map_util.h"
 #include "base/environment.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
@@ -58,6 +59,8 @@ const char kFreedesktopPortalName[] = "org.freedesktop.portal.Desktop";
 const char kFreedesktopPortalPath[] = "/org/freedesktop/portal/desktop";
 const char kFreedesktopPortalOpenURI[] = "org.freedesktop.portal.OpenURI";
 
+const char kOriginalXdgCurrentDesktopEnvVar[] = "ORIGINAL_XDG_CURRENT_DESKTOP";
+
 const char kMethodOpenDirectory[] = "OpenDirectory";
 
 class ShowItemHelper {
@@ -282,6 +285,12 @@ bool XDGUtil(const std::vector<std::string>& argv,
     base::nix::CreateLaunchOptionsWithXdgActivation(base::BindOnce(
         [](base::RepeatingClosure quit_loop, base::LaunchOptions* options_out,
            base::LaunchOptions options) {
+          // Correct the XDG_CURRENT_DESKTOP environment variable before calling
+          // XDG, in case it was changed for compatibility.
+          if (const auto* orig = base::FindOrNull(
+                  options.environment, kOriginalXdgCurrentDesktopEnvVar))
+            options.environment.emplace(base::nix::kXdgCurrentDesktopEnvVar,
+                                        *orig);
           *options_out = std::move(options);
           std::move(quit_loop).Run();
         },


Test patch: