diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 484a048b431e..a9a8acba7382 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -4507,6 +4507,12 @@ int XREMain::XRE_mainInit(bool* aExitFlag) { *aExitFlag = true; return 0; } + +# ifdef MOZ_WIDGET_GTK + if (XRE_IsParentProcess()) { + widget::RegisterHostApp(); + } +# endif #endif rv = XRE_InitCommandLine(gArgc, gArgv); diff --git a/widget/gtk/WidgetUtilsGtk.cpp b/widget/gtk/WidgetUtilsGtk.cpp index 339994bb7a3a..30c221b4d335 100644 --- a/widget/gtk/WidgetUtilsGtk.cpp +++ b/widget/gtk/WidgetUtilsGtk.cpp @@ -28,6 +28,11 @@ #include #include +#ifdef MOZ_ENABLE_DBUS +# include "mozilla/ClearOnShutdown.h" +# include "mozilla/widget/AsyncDBus.h" +#endif // MOZ_ENABLE_DBUS + #ifdef MOZ_WAYLAND # include "nsWaylandDisplay.h" #endif // MOZ_WAYLAND @@ -48,6 +53,13 @@ extern mozilla::LazyLogModule gWidgetLog; namespace mozilla::widget { +#ifdef MOZ_ENABLE_DBUS +constexpr char sXdpServiceName[] = "org.freedesktop.portal.Desktop"; +constexpr char sXdpDBusPath[] = "/org/freedesktop/portal/desktop"; +constexpr char sXdpRegistryInterfaceName[] = + "org.freedesktop.host.portal.Registry"; +#endif + int32_t WidgetUtilsGTK::IsTouchDeviceSupportPresent() { int32_t result = 0; GdkDisplay* display = gdk_display_get_default(); @@ -154,6 +166,75 @@ bool IsRunningUnderFlatpak() { return sRunning; } +#ifdef MOZ_ENABLE_DBUS +static void DoRegisterHostApp() { + GUniquePtr error; + + RefPtr proxy = dont_AddRef(g_dbus_proxy_new_for_bus_sync( + G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, nullptr, sXdpServiceName, + sXdpDBusPath, sXdpRegistryInterfaceName, nullptr /* cancellable */, + getter_Transfers(error))); + if (error) { + NS_WARNING( + nsPrintfCString("Failed to create DBus proxy : %s\n", error->message) + .get()); + return; + } + + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE("(sa{sv})")); + g_variant_builder_add(&builder, "s", "org.mozilla.firefox"); + GVariantBuilder dict_builder; + g_variant_builder_init(&dict_builder, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add_value(&builder, g_variant_builder_end(&dict_builder)); + + RefPtr args = + dont_AddRef(g_variant_ref_sink(g_variant_builder_end(&builder))); + + DBusProxyCall(proxy, "Register", args, G_DBUS_CALL_FLAGS_NONE, -1, + /* cancellable */ nullptr) + ->Then(GetCurrentSerialEventTarget(), __func__, + [](const DBusCallPromise::ResolveOrRejectValue& aValue) { + if (aValue.IsReject()) { + NS_WARNING( + "Failed to register host application for " + "portals\n"); + } + }); +} + +void RegisterHostApp() { + static bool sInitialized = false; + + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(XRE_IsParentProcess()); + MOZ_ASSERT(!sInitialized); + + // Register unsandboxed application with an application ID that will be used + // in portals. It has to be called before any other portal call, which + // happens with gtk_init or in our LookAndFeel code. We also need to + // re-register again when the portal is restarted. Documentation: + // https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.host.portal.Registry.xml + if (sInitialized || IsRunningUnderFlatpakOrSnap() || + g_getenv("XPCSHELL_TEST")) { + return; + } + + sInitialized = true; + + uint32_t DBusID = g_bus_watch_name( + G_BUS_TYPE_SESSION, sXdpServiceName, G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + [](GDBusConnection*, const gchar*, const gchar*, gpointer data) -> void { + DoRegisterHostApp(); + }, + nullptr, nullptr, nullptr); + + if (DBusID) { + RunOnShutdown([DBusID] { g_bus_unwatch_name(DBusID); }); + } +} +#endif + bool IsPackagedAppFileExists() { static bool sRunning = [] { nsresult rv; diff --git a/widget/gtk/WidgetUtilsGtk.h b/widget/gtk/WidgetUtilsGtk.h index 8d6f1d67279e..5bff5701b8ae 100644 --- a/widget/gtk/WidgetUtilsGtk.h +++ b/widget/gtk/WidgetUtilsGtk.h @@ -49,6 +49,9 @@ bool IsPackagedAppFileExists(); inline bool IsRunningUnderFlatpakOrSnap() { return IsRunningUnderFlatpak() || IsRunningUnderSnap(); } +#ifdef MOZ_ENABLE_DBUS +void RegisterHostApp(); +#endif enum class PortalKind { FilePicker, diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp index 117c1d6ae07c..99fd6dc87336 100644 --- a/widget/gtk/nsAppShell.cpp +++ b/widget/gtk/nsAppShell.cpp @@ -25,7 +25,6 @@ #include "nsIPowerManagerService.h" #ifdef MOZ_ENABLE_DBUS # include -# include "AsyncDBus.h" # include "nsIObserverService.h" # include "WidgetUtilsGtk.h" #endif @@ -49,13 +48,6 @@ using mozilla::widget::ScreenManager; #define NOTIFY_TOKEN 0xFA #define QUIT_TOKEN 0xFB -#ifdef MOZ_ENABLE_DBUS -constexpr char sXdpServiceName[] = "org.freedesktop.portal.Desktop"; -constexpr char sXdpDBusPath[] = "/org/freedesktop/portal/desktop"; -constexpr char sXdpRegistryInterfaceName[] = - "org.freedesktop.host.portal.Registry"; -#endif - LazyLogModule gWidgetLog("Widget"); LazyLogModule gWidgetDragLog("WidgetDrag"); LazyLogModule gWidgetWaylandLog("WidgetWayland"); @@ -173,10 +165,6 @@ nsAppShell::~nsAppShell() { #ifdef MOZ_ENABLE_DBUS StopDBusListening(); - if (mDBusID) { - g_bus_unwatch_name(mDBusID); - mDBusID = 0; - } #endif mozilla::hal::Shutdown(); @@ -336,45 +324,6 @@ void nsAppShell::StopDBusListening() { } mTimedate1Proxy = nullptr; } - -void nsAppShell::RegisterHostApp() { - GUniquePtr error; - RefPtr proxy; - RefPtr result; - - proxy = g_dbus_proxy_new_for_bus_sync( - G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, nullptr, sXdpServiceName, - sXdpDBusPath, sXdpRegistryInterfaceName, nullptr /* cancellable */, - getter_Transfers(error)); - if (error) { - NS_WARNING( - nsPrintfCString("Failed to create DBus proxy : %s\n", error->message) - .get()); - return; - } - - GVariantBuilder builder; - g_variant_builder_init(&builder, G_VARIANT_TYPE("(sa{sv})")); - g_variant_builder_add(&builder, "s", "org.mozilla.firefox"); - GVariantBuilder dict_builder; - g_variant_builder_init(&dict_builder, G_VARIANT_TYPE("a{sv}")); - g_variant_builder_add_value(&builder, g_variant_builder_end(&dict_builder)); - - RefPtr args = - dont_AddRef(g_variant_ref_sink(g_variant_builder_end(&builder))); - - widget::DBusProxyCall(proxy, "Register", args, G_DBUS_CALL_FLAGS_NONE, -1, - /* cancellable */ nullptr) - ->Then(GetCurrentSerialEventTarget(), __func__, - [](const mozilla::widget::DBusCallPromise::ResolveOrRejectValue& - aValue) { - if (aValue.IsReject()) { - NS_WARNING( - "Failed to register host application for " - "portals\n"); - } - }); -} #endif void nsAppShell::TermSignalHandler(int signo) { @@ -411,23 +360,6 @@ nsresult nsAppShell::Init() { #ifdef MOZ_ENABLE_DBUS if (XRE_IsParentProcess()) { StartDBusListening(); - - // Register unsandboxed application with an application ID that will be used - // in portals. It has to be called before any other portal call, which - // happens with gtk_init or in our LookAndFeel code. We also need to - // re-register again when the portal is restarted. Documentation: - // https://github.com/flatpak/xdg-desktop-portal/blob/main/data/org.freedesktop.host.portal.Registry.xml - if (!widget::IsRunningUnderFlatpakOrSnap() && !g_getenv("XPCSHELL_TEST")) { - mDBusID = g_bus_watch_name( - G_BUS_TYPE_SESSION, sXdpServiceName, - G_BUS_NAME_WATCHER_FLAGS_AUTO_START, - [](GDBusConnection*, const gchar*, const gchar*, - gpointer data) -> void { - auto* appShell = static_cast(data); - appShell->RegisterHostApp(); - }, - nullptr, this, nullptr); - } } #endif diff --git a/widget/gtk/nsAppShell.h b/widget/gtk/nsAppShell.h index 749057bb0672..ffbfb44c8902 100644 --- a/widget/gtk/nsAppShell.h +++ b/widget/gtk/nsAppShell.h @@ -60,7 +60,6 @@ class nsAppShell : public nsBaseAppShell { unsigned mTag = 0; #ifdef MOZ_ENABLE_DBUS - uint32_t mDBusID = 0; RefPtr mLogin1Proxy; RefPtr mLogin1ProxyCancellable; RefPtr mTimedate1Proxy;