diff options
| author | David Redondo <qt@david-redondo.de> | 2025-01-28 16:53:16 +0100 |
|---|---|---|
| committer | David Redondo <qt@david-redondo.de> | 2025-10-10 15:24:37 +0200 |
| commit | 9e4c03f4c9af4a64e82ce257508b512b82abbba2 (patch) | |
| tree | a9322fd606cbbfd17113c209f180b42544c7cf42 /src/gui/platform/unix/qdesktopunixservices.cpp | |
| parent | 0899651c8c0a827a90bad2bd31216b7b239a9807 (diff) | |
QDesktopUnixServices: Register with host app registry
This is useful when accessing portal APIs when not
sandboxed as it allows the portal to display info
which app is making the request. For example the dialog
that will be shown when QScreenCapture goes through the portal
can show the app name.
We need to do this as it can only be set before making
any call to the portal at all which are done here for color picking
or by the relevant platformthemes for settings.
See the paragraph at the top of
https://flatpak.github.io/xdg-desktop-portal/docs/api-reference.html and
https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.host.portal.Registry.html
Fixes: QTBUG-133401
Pick-to: 6.10
Change-Id: Ie55c371c6a19b3197f7798ee6233c2f19b18a6f6
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Diffstat (limited to 'src/gui/platform/unix/qdesktopunixservices.cpp')
| -rw-r--r-- | src/gui/platform/unix/qdesktopunixservices.cpp | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/src/gui/platform/unix/qdesktopunixservices.cpp b/src/gui/platform/unix/qdesktopunixservices.cpp index bbc6b41a2bc..d0ee636d484 100644 --- a/src/gui/platform/unix/qdesktopunixservices.cpp +++ b/src/gui/platform/unix/qdesktopunixservices.cpp @@ -29,6 +29,7 @@ #include <QtCore/QUrlQuery> #include <QtDBus/QDBusConnection> +#include <QtDBus/QDBusServiceWatcher> #include <QtDBus/QDBusMessage> #include <QtDBus/QDBusPendingCall> #include <QtDBus/QDBusPendingCallWatcher> @@ -373,6 +374,34 @@ private Q_SLOTS: private: const QString m_parentWindowId; }; + +void registerWithHostPortal() +{ + static bool registered = false; + if (registered) { + return; + } + + auto message = QDBusMessage::createMethodCall( + "org.freedesktop.portal.Desktop"_L1, "/org/freedesktop/portal/desktop"_L1, + "org.freedesktop.host.portal.Registry"_L1, "Register"_L1); + message.setArguments({ QGuiApplication::desktopFileName(), QVariantMap() }); + auto watcher = + new QDBusPendingCallWatcher(QDBusConnection::sessionBus().asyncCall(message), qGuiApp); + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [watcher] { + watcher->deleteLater(); + if (watcher->isError()) { + // Expected error when running against an older portal + if (watcher->error().type() == QDBusError::UnknownInterface || watcher->error().type() == QDBusError::UnknownMethod) + qCInfo(lcQpaServices) << "Failed to register with host portal" << watcher->error(); + else + qCWarning(lcQpaServices) << "Failed to register with host portal" << watcher->error(); + } else { + qCDebug(lcQpaServices) << "Successfully registered with host portal as" << QGuiApplication::desktopFileName(); + registered = true; + } + }); +} } // namespace #endif // QT_CONFIG(dbus) @@ -395,7 +424,7 @@ QDesktopUnixServices::QDesktopUnixServices() QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message); auto watcher = new QDBusPendingCallWatcher(pendingCall); m_watcher = watcher; - QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher, + QObject::connect(watcher, &QDBusPendingCallWatcher::finished, watcher, [this](QDBusPendingCallWatcher *watcher) { watcher->deleteLater(); QDBusPendingReply<QVariant> reply = *watcher; @@ -403,6 +432,31 @@ QDesktopUnixServices::QDesktopUnixServices() m_hasScreenshotPortalWithColorPicking = true; }); + if (checkNeedPortalSupport()) { + return; + } + + // The program might only set the desktopfilename after creating the app + // try again when it's running + if (!QGuiApplication::desktopFileName().isEmpty()) { + registerWithHostPortal(); + } else { + QMetaObject::invokeMethod( + qGuiApp, + [] { + if (QGuiApplication::desktopFileName().isEmpty()) { + qCInfo(lcQpaServices) << "QGuiApplication::desktopFileName not set. Unable to register application with portal registry"; + return; + } + registerWithHostPortal(); + }, + Qt::QueuedConnection); + } + m_portalWatcher = std::make_unique<QDBusServiceWatcher>( + "org.freedesktop.portal.Desktop"_L1, QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForRegistration); + QObject::connect(m_portalWatcher.get(), &QDBusServiceWatcher::serviceRegistered, + m_portalWatcher.get(), ®isterWithHostPortal); #endif } |
