Bug 1804877 [Wayland] Use RequestWaylandFocus()/XDG token in nsGIOService to launch external applications r=emilio

Depends on D165151

Differential Revision: https://phabricator.services.mozilla.com/D165152
This commit is contained in:
stransky 2023-01-03 22:20:19 +00:00
Родитель 082abc592f
Коммит 13bc9c5768
1 изменённых файлов: 72 добавлений и 14 удалений

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/WidgetUtilsGtk.h" #include "mozilla/WidgetUtilsGtk.h"
#include "mozilla/StaticPrefs_widget.h" #include "mozilla/StaticPrefs_widget.h"
#include "mozilla/net/DNS.h" #include "mozilla/net/DNS.h"
#include "prenv.h"
#include <gio/gio.h> #include <gio/gio.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
@ -216,7 +217,8 @@ nsGIOMimeApp::Equals(nsIHandlerApp* aHandlerApp, bool* _retval) {
return NS_OK; return NS_OK;
} }
static RefPtr<GAppLaunchContext> GetLaunchContext() { static RefPtr<GAppLaunchContext> GetLaunchContext(
const char* aXDGToken = nullptr) {
RefPtr<GAppLaunchContext> context = dont_AddRef(g_app_launch_context_new()); RefPtr<GAppLaunchContext> context = dont_AddRef(g_app_launch_context_new());
// Unset this before launching third-party MIME handlers. Otherwise, if // Unset this before launching third-party MIME handlers. Otherwise, if
// Thunderbird sets this in its startup script (as it does in Debian and // Thunderbird sets this in its startup script (as it does in Debian and
@ -224,6 +226,9 @@ static RefPtr<GAppLaunchContext> GetLaunchContext() {
// Debian), then Firefox will think it is part of Thunderbird and try to make // Debian), then Firefox will think it is part of Thunderbird and try to make
// Thunderbird the default browser. See bug 1494436. // Thunderbird the default browser. See bug 1494436.
g_app_launch_context_unsetenv(context, "MOZ_APP_LAUNCHER"); g_app_launch_context_unsetenv(context, "MOZ_APP_LAUNCHER");
if (aXDGToken) {
g_app_launch_context_setenv(context, "XDG_ACTIVATION_TOKEN", aXDGToken);
}
return context; return context;
} }
@ -280,9 +285,8 @@ gboolean g_app_info_launch_default_for_uri_openbsd(const char* uri,
} }
#endif #endif
NS_IMETHODIMP static NS_IMETHODIMP LaunchWithURIImpl(RefPtr<GAppInfo> aInfo, nsIURI* aUri,
nsGIOMimeApp::LaunchWithURI(nsIURI* aUri, const char* aXDGToken = nullptr) {
mozilla::dom::BrowsingContext* aBrowsingContext) {
GList uris = {0}; GList uris = {0};
nsCString spec; nsCString spec;
aUri->GetSpec(spec); aUri->GetSpec(spec);
@ -292,10 +296,11 @@ nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
GUniquePtr<GError> error; GUniquePtr<GError> error;
#ifdef __OpenBSD__ #ifdef __OpenBSD__
gboolean result = g_app_info_launch_uris_openbsd( gboolean result = g_app_info_launch_uris_openbsd(
mApp, spec.get(), GetLaunchContext().get(), getter_Transfers(error)); aInfo, spec.get(), GetLaunchContext(aXDGToken).get(),
getter_Transfers(error));
#else #else
gboolean result = g_app_info_launch_uris( gboolean result = g_app_info_launch_uris(
mApp, &uris, GetLaunchContext().get(), getter_Transfers(error)); aInfo, &uris, GetLaunchContext(aXDGToken).get(), getter_Transfers(error));
#endif #endif
if (!result) { if (!result) {
g_warning("Cannot launch application: %s", error->message); g_warning("Cannot launch application: %s", error->message);
@ -305,6 +310,26 @@ nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsGIOMimeApp::LaunchWithURI(nsIURI* aUri,
mozilla::dom::BrowsingContext* aBrowsingContext) {
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (!promise) {
return LaunchWithURIImpl(mApp, aUri);
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[app = RefPtr{mApp}, uri = RefPtr{aUri}](nsCString token) {
LaunchWithURIImpl(app, uri, token.get());
},
/* reject */
[app = RefPtr{mApp}, uri = RefPtr{aUri}](bool state) {
LaunchWithURIImpl(app, uri);
});
return NS_OK;
}
class GIOUTF8StringEnumerator final : public nsStringEnumeratorBase { class GIOUTF8StringEnumerator final : public nsStringEnumeratorBase {
~GIOUTF8StringEnumerator() = default; ~GIOUTF8StringEnumerator() = default;
@ -593,17 +618,18 @@ nsGIOService::GetDescriptionForMimeType(const nsACString& aMimeType,
return NS_OK; return NS_OK;
} }
nsresult nsGIOService::ShowURI(nsIURI* aURI) { static nsresult ShowURIImpl(nsIURI* aURI, const char* aXDGToken = nullptr) {
nsAutoCString spec; nsAutoCString spec;
MOZ_TRY(aURI->GetSpec(spec)); MOZ_TRY(aURI->GetSpec(spec));
GUniquePtr<GError> error; GUniquePtr<GError> error;
#ifdef __OpenBSD__ #ifdef __OpenBSD__
if (!g_app_info_launch_default_for_uri_openbsd(spec.get(), if (!g_app_info_launch_default_for_uri_openbsd(
GetLaunchContext().get(), spec.get(), GetLaunchContext(aXDGToken).get(),
#else #else
if (!g_app_info_launch_default_for_uri(spec.get(), GetLaunchContext().get(), if (!g_app_info_launch_default_for_uri(spec.get(),
GetLaunchContext(aXDGToken).get(),
#endif #endif
getter_Transfers(error))) { getter_Transfers(error))) {
g_warning("Could not launch default application for URI: %s", g_warning("Could not launch default application for URI: %s",
error->message); error->message);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -611,16 +637,32 @@ nsresult nsGIOService::ShowURI(nsIURI* aURI) {
return NS_OK; return NS_OK;
} }
static nsresult LaunchPath(const nsACString& aPath) { nsresult nsGIOService::ShowURI(nsIURI* aURI) {
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (!promise) {
return ShowURIImpl(aURI);
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[uri = RefPtr{aURI}](nsCString token) { ShowURIImpl(uri, token.get()); },
/* reject */
[uri = RefPtr{aURI}](bool state) { ShowURIImpl(uri); });
return NS_OK;
}
static nsresult LaunchPathImpl(const nsACString& aPath,
const char* aXDGToken = nullptr) {
RefPtr<GFile> file = dont_AddRef( RefPtr<GFile> file = dont_AddRef(
g_file_new_for_commandline_arg(PromiseFlatCString(aPath).get())); g_file_new_for_commandline_arg(PromiseFlatCString(aPath).get()));
GUniquePtr<char> spec(g_file_get_uri(file)); GUniquePtr<char> spec(g_file_get_uri(file));
GUniquePtr<GError> error; GUniquePtr<GError> error;
#ifdef __OpenBSD__ #ifdef __OpenBSD__
g_app_info_launch_default_for_uri_openbsd(spec.get(), g_app_info_launch_default_for_uri_openbsd(spec.get(),
GetLaunchContext().get(), GetLaunchContext(aXDGToken).get(),
#else #else
g_app_info_launch_default_for_uri(spec.get(), GetLaunchContext().get(), g_app_info_launch_default_for_uri(spec.get(),
GetLaunchContext(aXDGToken).get(),
#endif #endif
getter_Transfers(error)); getter_Transfers(error));
if (error) { if (error) {
@ -630,6 +672,22 @@ static nsresult LaunchPath(const nsACString& aPath) {
return NS_OK; return NS_OK;
} }
static nsresult LaunchPath(const nsACString& aPath) {
auto promise = mozilla::widget::RequestWaylandFocusPromise();
if (!promise) {
return LaunchPathImpl(aPath);
}
promise->Then(
GetMainThreadSerialEventTarget(), __func__,
/* resolve */
[path = nsCString{aPath}](nsCString token) {
LaunchPathImpl(path, token.get());
},
/* reject */
[path = nsCString{aPath}](bool state) { LaunchPathImpl(path); });
return NS_OK;
}
nsresult nsGIOService::LaunchFile(const nsACString& aPath) { nsresult nsGIOService::LaunchFile(const nsACString& aPath) {
return LaunchPath(aPath); return LaunchPath(aPath);
} }