diff --git a/shell/app/electron_main_delegate.cc b/shell/app/electron_main_delegate.cc index a6f30149b496..886f46a1adcd 100644 --- a/shell/app/electron_main_delegate.cc +++ b/shell/app/electron_main_delegate.cc @@ -408,6 +408,11 @@ std::optional ElectronMainDelegate::PreBrowserMain() { content::InitializeMojoCore(); #if BUILDFLAG(IS_MAC) RegisterAtomCrApp(); +#endif +#if BUILDFLAG(IS_LINUX) + // Set the global activation token sent as an environment variable. + auto env = base::Environment::Create(); + base::nix::ExtractXdgActivationTokenFromEnv(*env); #endif return std::nullopt; } diff --git a/shell/browser/api/electron_api_app.cc b/shell/browser/api/electron_api_app.cc index 5b0e7b0dd0f5..09c5d1bbffb4 100644 --- a/shell/browser/api/electron_api_app.cc +++ b/shell/browser/api/electron_api_app.cc @@ -92,6 +92,11 @@ #include "shell/browser/ui/cocoa/electron_bundle_mover.h" #endif +#if BUILDFLAG(IS_LINUX) +#include "base/nix/scoped_xdg_activation_token_injector.h" +#include "base/nix/xdg_util.h" +#endif + using electron::Browser; namespace gin { @@ -411,6 +416,12 @@ bool NotificationCallbackWrapper( base::CommandLine cmd, const base::FilePath& cwd, const std::vector additional_data) { +#if BUILDFLAG(IS_LINUX) + // Set the global activation token sent as a command line switch by another + // electron app instance. This also removes the switch after use to prevent + // any side effects of leaving it in the command line after this point. + base::nix::ExtractXdgActivationTokenFromCmdLine(cmd); +#endif // Make sure the callback is called after app gets ready. if (Browser::Get()->is_ready()) { callback.Run(std::move(cmd), cwd, std::move(additional_data)); @@ -1021,6 +1032,15 @@ bool App::RequestSingleInstanceLock(gin::Arguments* args) { base::BindRepeating(NotificationCallbackWrapper, cb)); #endif +#if BUILDFLAG(IS_LINUX) + // Read the xdg-activation token and set it in the command line for the + // duration of the notification in order to ensure this is propagated to an + // already running electron app instance if it exists. + // The activation token received from the launching app is used later when + // activating the existing electron app instance window. + base::nix::ScopedXdgActivationTokenInjector activation_token_injector( + *base::CommandLine::ForCurrentProcess(), *base::Environment::Create()); +#endif switch (process_singleton_->NotifyOtherProcessOrCreate()) { case ProcessSingleton::NotifyResult::PROCESS_NONE: if (content::BrowserThread::IsThreadInitialized(