commit:     e3e36c9794b4defc7012f19a3efa3a09c12cab71
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat May  6 09:30:19 2023 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat May  6 09:40:08 2023 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=e3e36c97

sys-apps/xdg-desktop-portal: add delay/slowness backport

>From the 1.16 branch upstream & backported in Fedora as well.

Bug: https://bugs.gentoo.org/905482
Signed-off-by: Sam James <sam <AT> gentoo.org>

 .../xdg-desktop-portal-1.16.0-delay-open-fix.patch | 300 +++++++++++++++++++++
 .../xdg-desktop-portal-1.16.0-r1.ebuild            |  68 +++++
 2 files changed, 368 insertions(+)

diff --git 
a/sys-apps/xdg-desktop-portal/files/xdg-desktop-portal-1.16.0-delay-open-fix.patch
 
b/sys-apps/xdg-desktop-portal/files/xdg-desktop-portal-1.16.0-delay-open-fix.patch
new file mode 100644
index 000000000000..1e1598744c46
--- /dev/null
+++ 
b/sys-apps/xdg-desktop-portal/files/xdg-desktop-portal-1.16.0-delay-open-fix.patch
@@ -0,0 +1,300 @@
+https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/issues/74
+https://github.com/flatpak/xdg-desktop-portal/pull/985
+https://github.com/flatpak/xdg-desktop-portal/commit/2a219279997c2124c8a639b0d009c9946ec97b40
+
+Fedora's backported it as well at 
https://gitlab.gnome.org/GNOME/xdg-desktop-portal-gnome/-/issues/74.
+
+From 2a219279997c2124c8a639b0d009c9946ec97b40 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20=C3=85dahl?= <[email protected]>
+Date: Mon, 13 Mar 2023 12:38:17 +0100
+Subject: [PATCH] portal-impl: Only return found implementation if it launched
+
+If no portal backend for a given interface is found, a fallback is
+always tried anyway, despite that fallback not being listed as
+compatible with the current desktop environment.
+
+Sometimes it's good that a fallback is returned; e.g. the
+xdg-desktop-portal-gtk file chooser backend is technically usable
+anywhere, however, some backends might be specifically designed to only
+work in a specific desktop environment, e.g. xdg-desktop-portal-gnome.
+
+In order to avoid creating portals with non-functional backends, make
+sure it's possible to create a proxy object for the interface and D-Bus
+name, and that it launched successfully (i.e. has no name owner after
+creating the proxy).
+--- a/src/portal-impl.c
++++ b/src/portal-impl.c
+@@ -29,9 +29,12 @@
+ #include <glib.h>
+ #include <gio/gio.h>
+ 
++#include "xdp-utils.h"
++
+ static void
+ portal_implementation_free (PortalImplementation *impl)
+ {
++  g_clear_pointer (&impl->dummy_proxies, g_hash_table_unref);
+   g_free (impl->source);
+   g_free (impl->dbus_name);
+   g_strfreev (impl->interfaces);
+@@ -55,6 +58,10 @@ register_portal (const char *path, gboolean opt_verbose, 
GError **error)
+   if (!g_key_file_load_from_file (keyfile, path, G_KEY_FILE_NONE, error))
+     return FALSE;
+ 
++  impl->dummy_proxies = g_hash_table_new_full (g_str_hash,
++                                               g_str_equal,
++                                               g_free,
++                                               g_object_unref);
+   impl->source = g_path_get_basename (path);
+   impl->dbus_name = g_key_file_get_string (keyfile, "portal", "DBusName", 
error);
+   if (impl->dbus_name == NULL)
+@@ -198,8 +205,44 @@ load_installed_portals (gboolean opt_verbose)
+   implementations = g_list_sort (implementations, 
sort_impl_by_use_in_and_name);
+ }
+ 
++static gboolean
++create_dummy_proxy (PortalImplementation  *impl,
++                    GDBusConnection       *connection,
++                    const char            *interface,
++                    GError               **error)
++{
++  g_autoptr(GDBusProxy) proxy = NULL;
++
++  g_debug ("Creating dummy proxy for %s on %s", interface, impl->dbus_name);
++  proxy = g_dbus_proxy_new_sync (connection,
++                                 G_DBUS_PROXY_FLAGS_NONE,
++                                 NULL,
++                                 impl->dbus_name,
++                                 DESKTOP_PORTAL_OBJECT_PATH,
++                                 interface,
++                                 NULL,
++                                 error);
++  if (!proxy)
++    return FALSE;
++
++  if (!g_dbus_proxy_get_name_owner (proxy))
++    {
++      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
++                   "Proxy has no owner");
++      return FALSE;
++    }
++
++  g_debug ("Dummy proxy created");
++
++  g_hash_table_insert (impl->dummy_proxies,
++                       g_strdup (interface),
++                       g_steal_pointer (&proxy));
++  return TRUE;
++}
++
+ PortalImplementation *
+-find_portal_implementation (const char *interface)
++find_portal_implementation (GDBusConnection *connection,
++                            const char      *interface)
+ {
+   const char *desktops_str = g_getenv ("XDG_CURRENT_DESKTOP");
+   g_auto(GStrv) desktops = NULL;
+@@ -216,15 +259,23 @@ find_portal_implementation (const char *interface)
+      for (l = implementations; l != NULL; l = l->next)
+         {
+           PortalImplementation *impl = l->data;
++          g_autoptr(GError) error = NULL;
+ 
+           if (!g_strv_contains ((const char **)impl->interfaces, interface))
+             continue;
+ 
+-          if (g_strv_case_contains ((const char **)impl->use_in, desktops[i]))
++          if (!g_strv_case_contains ((const char **)impl->use_in, 
desktops[i]))
++            continue;
++
++          if (!create_dummy_proxy (impl, connection, interface, &error))
+             {
+-              g_debug ("Using %s for %s in %s", impl->source, interface, 
desktops[i]);
+-              return impl;
++              g_debug ("Failed to create dummy proxy on %s for %s: %s",
++                       impl->dbus_name, interface, error->message);
++              continue;
+             }
++
++          g_debug ("Using %s for %s in %s", impl->source, interface, 
desktops[i]);
++          return impl;
+         }
+     }
+ 
+@@ -232,10 +283,18 @@ find_portal_implementation (const char *interface)
+   for (l = implementations; l != NULL; l = l->next)
+     {
+       PortalImplementation *impl = l->data;
++      g_autoptr(GError) error = NULL;
+ 
+       if (!g_strv_contains ((const char **)impl->interfaces, interface))
+         continue;
+ 
++      if (!create_dummy_proxy (impl, connection, interface, &error))
++        {
++          g_debug ("Failed to create dummy fallback proxy on %s for %s: %s",
++                   impl->dbus_name, interface, error->message);
++          continue;
++        }
++
+       g_debug ("Falling back to %s for %s", impl->source, interface);
+       return impl;
+     }
+--- a/src/portal-impl.h
++++ b/src/portal-impl.h
+@@ -23,6 +23,7 @@
+ #define __PORTAL_IMPL_H__
+ 
+ #include <glib.h>
++#include <gio/gio.h>
+ 
+ typedef struct {
+   char *source;
+@@ -30,10 +31,12 @@ typedef struct {
+   char **interfaces;
+   char **use_in;
+   int priority;
++  GHashTable *dummy_proxies;
+ } PortalImplementation;
+ 
+ void                  load_installed_portals          (gboolean opt_verbose);
+-PortalImplementation *find_portal_implementation      (const char *interface);
++PortalImplementation *find_portal_implementation      (GDBusConnection 
*connection,
++                                                       const char *interface);
+ GPtrArray            *find_all_portal_implementations (const char *interface);
+ 
+ #endif  /* __PORTAL_IMPL_H__ */
+--- a/src/xdg-desktop-portal.c
++++ b/src/xdg-desktop-portal.c
+@@ -237,7 +237,8 @@ on_bus_acquired (GDBusConnection *connection,
+   init_document_proxy (connection);
+   init_permission_store (connection);
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Lockdown");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Lockdown");
+   if (implementation != NULL)
+     lockdown = xdp_dbus_impl_lockdown_proxy_new_sync (connection,
+                                                       G_DBUS_PROXY_FLAGS_NONE,
+@@ -259,40 +260,48 @@ on_bus_acquired (GDBusConnection *connection,
+   export_portal_implementation (connection, settings_create (connection, 
impls));
+   g_ptr_array_free (impls, TRUE);
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.FileChooser");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.FileChooser");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   file_chooser_create (connection, 
implementation->dbus_name, lockdown));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.AppChooser");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.AppChooser");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   open_uri_create (connection, 
implementation->dbus_name, lockdown));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Print");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Print");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   print_create (connection, 
implementation->dbus_name, lockdown));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Notification");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Notification");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   notification_create (connection, 
implementation->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Inhibit");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Inhibit");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   inhibit_create (connection, 
implementation->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Access");
+-  implementation2 = find_portal_implementation 
("org.freedesktop.impl.portal.Screenshot");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Access");
++  implementation2 = find_portal_implementation (connection,
++                                                
"org.freedesktop.impl.portal.Screenshot");
+   if (implementation != NULL && implementation2 != NULL)
+     export_portal_implementation (connection,
+                                   screenshot_create (connection,
+                                                      
implementation->dbus_name,
+                                                      
implementation2->dbus_name));
+ 
+-  implementation2 = find_portal_implementation 
("org.freedesktop.impl.portal.Background");
++  implementation2 = find_portal_implementation (connection,
++                                                
"org.freedesktop.impl.portal.Background");
+   if (implementation != NULL)
+     {
+       export_portal_implementation (connection,
+@@ -313,47 +322,55 @@ on_bus_acquired (GDBusConnection *connection,
+                                                      
implementation->dbus_name,
+                                                      
implementation2->dbus_name));
+ 
+-  implementation2 = find_portal_implementation 
("org.freedesktop.impl.portal.Wallpaper");
++  implementation2 = find_portal_implementation (connection,
++                                                
"org.freedesktop.impl.portal.Wallpaper");
+   if (implementation != NULL && implementation2 != NULL)
+     export_portal_implementation (connection,
+                                   wallpaper_create (connection,
+                                                     implementation->dbus_name,
+                                                     
implementation2->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Account");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Account");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   account_create (connection, 
implementation->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Email");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Email");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   email_create (connection, 
implementation->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.Secret");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.Secret");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   secret_create (connection, 
implementation->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.GlobalShortcuts");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.GlobalShortcuts");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   global_shortcuts_create (connection, 
implementation->dbus_name));
+ 
+ #ifdef HAVE_GLIB_2_66
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.DynamicLauncher");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.DynamicLauncher");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   dynamic_launcher_create (connection, 
implementation->dbus_name));
+ #endif
+ 
+ #ifdef HAVE_PIPEWIRE
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.ScreenCast");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.ScreenCast");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   screen_cast_create (connection, 
implementation->dbus_name));
+ 
+-  implementation = find_portal_implementation 
("org.freedesktop.impl.portal.RemoteDesktop");
++  implementation = find_portal_implementation (connection,
++                                               
"org.freedesktop.impl.portal.RemoteDesktop");
+   if (implementation != NULL)
+     export_portal_implementation (connection,
+                                   remote_desktop_create (connection, 
implementation->dbus_name));
+

diff --git a/sys-apps/xdg-desktop-portal/xdg-desktop-portal-1.16.0-r1.ebuild 
b/sys-apps/xdg-desktop-portal/xdg-desktop-portal-1.16.0-r1.ebuild
new file mode 100644
index 000000000000..3a9bda386772
--- /dev/null
+++ b/sys-apps/xdg-desktop-portal/xdg-desktop-portal-1.16.0-r1.ebuild
@@ -0,0 +1,68 @@
+# Copyright 1999-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit autotools systemd
+
+DESCRIPTION="Desktop integration portal"
+HOMEPAGE="https://flatpak.org/ https://github.com/flatpak/xdg-desktop-portal";
+SRC_URI="https://github.com/flatpak/${PN}/releases/download/${PV}/${P}.tar.xz";
+
+LICENSE="LGPL-2.1"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~arm64 ~loong ~ppc ~ppc64 ~riscv ~x86"
+IUSE="geolocation screencast systemd"
+
+DEPEND="
+       >=dev-libs/glib-2.66:2
+       dev-libs/json-glib
+       >=sys-fs/fuse-3.10.0:3[suid]
+       x11-libs/gdk-pixbuf
+       geolocation? ( >=app-misc/geoclue-2.5.3:2.0 )
+       screencast? ( >=media-video/pipewire-0.3:= )
+       systemd? ( sys-apps/systemd )
+"
+RDEPEND="${DEPEND}
+       sys-apps/dbus
+"
+BDEPEND="
+       dev-util/gdbus-codegen
+       sys-devel/gettext
+       virtual/pkgconfig
+"
+
+PATCHES=(
+       "${FILESDIR}"/${P}-delay-open-fix.patch
+)
+
+src_prepare() {
+       default
+       eautoreconf
+}
+
+src_configure() {
+       local myeconfargs=(
+               --disable-docbook-docs # requires flatpak
+               --disable-libportal # not packaged
+               --with-systemduserunitdir="$(systemd_get_userunitdir)"
+               $(use_enable geolocation geoclue)
+               $(use_enable screencast pipewire)
+               $(use_with systemd)
+       )
+       econf "${myeconfargs[@]}"
+}
+
+pkg_postinst() {
+       if ! has_version gui-libs/xdg-desktop-portal-lxqt && ! has_version 
gui-libs/xdg-desktop-portal-wlr && \
+               ! has_version kde-plasma/xdg-desktop-portal-kde && ! 
has_version sys-apps/xdg-desktop-portal-gnome && \
+               ! has_version sys-apps/xdg-desktop-portal-gtk; then
+               elog "${PN} is not usable without any of the following XDP"
+               elog "implementations installed:"
+               elog "  gui-libs/xdg-desktop-portal-lxqt"
+               elog "  gui-libs/xdg-desktop-portal-wlr"
+               elog "  kde-plasma/xdg-desktop-portal-kde"
+               elog "  sys-apps/xdg-desktop-portal-gnome"
+               elog "  sys-apps/xdg-desktop-portal-gtk"
+       fi
+}

Reply via email to