summaryrefslogtreecommitdiffstats
path: root/src/gui/platform/unix/qdesktopunixservices.cpp
diff options
context:
space:
mode:
authorDavid Redondo <qt@david-redondo.de>2025-01-28 16:53:16 +0100
committerDavid Redondo <qt@david-redondo.de>2025-10-10 15:24:37 +0200
commit9e4c03f4c9af4a64e82ce257508b512b82abbba2 (patch)
treea9322fd606cbbfd17113c209f180b42544c7cf42 /src/gui/platform/unix/qdesktopunixservices.cpp
parent0899651c8c0a827a90bad2bd31216b7b239a9807 (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.cpp56
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(), &registerWithHostPortal);
#endif
}