summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Redondo <qt@david-redondo.de>2022-02-23 11:12:17 +0100
committerDavid Redondo <qt@david-redondo.de>2022-07-25 18:29:49 +0200
commitc142fd8f686aa86e333cb3f30a4d3802155ecae5 (patch)
treed84076fae08e3f5939995f49db259ffa27e53555
parentf3cd57168731c67afd12d8071ead96eed1177b25 (diff)
Send parent_window handle to desktop portal
Sending parent_window to the portal allows it/the window manager to better place portal dialogs in respect to the application window, for example on top of it instead of a random position. For this use the focusWindow() (if available) since the API in QDesktopServices does not take a QWindow parameter. The file dialog has an explicit parent that can be used. The introduced virtual is provided as a hook for the wayland platform that already includes a class that inherits from QGenericUnixServices. Change-Id: I5571f08d07e5a4e3ae32efd1f09e2727cec9e7c5 Reviewed-by: David Edmundson <davidedmundson@kde.org>
-rw-r--r--src/gui/platform/unix/qgenericunixservices.cpp40
-rw-r--r--src/gui/platform/unix/qgenericunixservices_p.h4
-rw-r--r--src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp15
3 files changed, 45 insertions, 14 deletions
diff --git a/src/gui/platform/unix/qgenericunixservices.cpp b/src/gui/platform/unix/qgenericunixservices.cpp
index a0e5466c58..54a0406cab 100644
--- a/src/gui/platform/unix/qgenericunixservices.cpp
+++ b/src/gui/platform/unix/qgenericunixservices.cpp
@@ -3,6 +3,8 @@
#include "qgenericunixservices_p.h"
#include <QtGui/private/qtguiglobal_p.h>
+#include "qguiapplication.h"
+#include "qwindow.h"
#include <QtCore/QDebug>
#include <QtCore/QFile>
@@ -152,7 +154,7 @@ static inline bool checkNeedPortalSupport()
return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, "flatpak-info"_L1).isEmpty() || qEnvironmentVariableIsSet("SNAP");
}
-static inline QDBusMessage xdgDesktopPortalOpenFile(const QUrl &url)
+static inline QDBusMessage xdgDesktopPortalOpenFile(const QUrl &url, const QString &parentWindow)
{
// DBus signature:
// OpenFile (IN s parent_window,
@@ -176,19 +178,19 @@ static inline QDBusMessage xdgDesktopPortalOpenFile(const QUrl &url)
const QVariantMap options = {{"writable"_L1, true}};
- // FIXME parent_window_id
- message << QString() << QVariant::fromValue(descriptor) << options;
+ message << parentWindow << QVariant::fromValue(descriptor) << options;
return QDBusConnection::sessionBus().call(message);
}
#else
Q_UNUSED(url);
+ Q_UNUSED(parentWindow)
#endif
return QDBusMessage::createError(QDBusError::InternalError, qt_error_string());
}
-static inline QDBusMessage xdgDesktopPortalOpenUrl(const QUrl &url)
+static inline QDBusMessage xdgDesktopPortalOpenUrl(const QUrl &url, const QString &parentWindow)
{
// DBus signature:
// OpenURI (IN s parent_window,
@@ -206,12 +208,12 @@ static inline QDBusMessage xdgDesktopPortalOpenUrl(const QUrl &url)
"org.freedesktop.portal.OpenURI"_L1,
"OpenURI"_L1);
// FIXME parent_window_id and handle writable option
- message << QString() << url.toString() << QVariantMap();
+ message << parentWindow << url.toString() << QVariantMap();
return QDBusConnection::sessionBus().call(message);
}
-static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
+static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url, const QString &parentWindow)
{
// DBus signature:
// ComposeEmail (IN s parent_window,
@@ -251,8 +253,7 @@ static inline QDBusMessage xdgDesktopPortalSendEmail(const QUrl &url)
"org.freedesktop.portal.Email"_L1,
"ComposeEmail"_L1);
- // FIXME parent_window_id
- message << QString() << options;
+ message << parentWindow << options;
return QDBusConnection::sessionBus().call(message);
}
@@ -269,7 +270,10 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
if (url.scheme() == "mailto"_L1) {
#if QT_CONFIG(dbus)
if (checkNeedPortalSupport()) {
- QDBusError error = xdgDesktopPortalSendEmail(url);
+ const QString parentWindow = QGuiApplication::focusWindow()
+ ? portalWindowIdentifier(QGuiApplication::focusWindow())
+ : QString();
+ QDBusError error = xdgDesktopPortalSendEmail(url, parentWindow);
if (!error.isValid())
return true;
@@ -281,7 +285,10 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
#if QT_CONFIG(dbus)
if (checkNeedPortalSupport()) {
- QDBusError error = xdgDesktopPortalOpenUrl(url);
+ const QString parentWindow = QGuiApplication::focusWindow()
+ ? portalWindowIdentifier(QGuiApplication::focusWindow())
+ : QString();
+ QDBusError error = xdgDesktopPortalOpenUrl(url, parentWindow);
if (!error.isValid())
return true;
}
@@ -298,7 +305,10 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
{
#if QT_CONFIG(dbus)
if (checkNeedPortalSupport()) {
- QDBusError error = xdgDesktopPortalOpenFile(url);
+ const QString parentWindow = QGuiApplication::focusWindow()
+ ? portalWindowIdentifier(QGuiApplication::focusWindow())
+ : QString();
+ QDBusError error = xdgDesktopPortalOpenFile(url, parentWindow);
if (!error.isValid())
return true;
}
@@ -333,4 +343,12 @@ bool QGenericUnixServices::openDocument(const QUrl &url)
#endif // QT_NO_MULTIPROCESS
+QString QGenericUnixServices::portalWindowIdentifier(QWindow *window)
+{
+ if (QGuiApplication::platformName() == QLatin1String("xcb"))
+ return "x11:"_L1 + QString::number(window->winId(), 16);
+
+ return QString();
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/platform/unix/qgenericunixservices_p.h b/src/gui/platform/unix/qgenericunixservices_p.h
index 8d1228375f..2ddba91a3a 100644
--- a/src/gui/platform/unix/qgenericunixservices_p.h
+++ b/src/gui/platform/unix/qgenericunixservices_p.h
@@ -21,6 +21,8 @@
QT_BEGIN_NAMESPACE
+class QWindow;
+
class Q_GUI_EXPORT QGenericUnixServices : public QPlatformServices
{
public:
@@ -31,6 +33,8 @@ public:
bool openUrl(const QUrl &url) override;
bool openDocument(const QUrl &url) override;
+ virtual QString portalWindowIdentifier(QWindow *window);
+
private:
QString m_webBrowser;
QString m_documentLauncher;
diff --git a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
index ecc5545e76..2ef591a591 100644
--- a/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
+++ b/src/plugins/platformthemes/xdgdesktopportal/qxdgdesktopportalfiledialog.cpp
@@ -3,6 +3,10 @@
#include "qxdgdesktopportalfiledialog_p.h"
+#include <private/qgenericunixservices_p.h>
+#include <private/qguiapplication_p.h>
+#include <qpa/qplatformintegration.h>
+
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusPendingCall>
@@ -157,8 +161,6 @@ void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::Wi
"/org/freedesktop/portal/desktop"_L1,
"org.freedesktop.portal.FileChooser"_L1,
d->saveFile ? "SaveFile"_L1 : "OpenFile"_L1);
- QString parentWindowId = "x11:"_L1 + QString::number(parent ? parent->winId() : 0, 16);
-
QVariantMap options;
if (!d->acceptLabel.isEmpty())
options.insert("accept_label"_L1, d->acceptLabel);
@@ -262,7 +264,14 @@ void QXdgDesktopPortalFileDialog::openPortal(Qt::WindowFlags windowFlags, Qt::Wi
// TODO choices a(ssa(ss)s)
// List of serialized combo boxes to add to the file chooser.
- message << parentWindowId << d->title << options;
+ auto unixServices = dynamic_cast<QGenericUnixServices *>(
+ QGuiApplicationPrivate::platformIntegration()->services());
+ if (parent && unixServices)
+ message << unixServices->portalWindowIdentifier(parent);
+ else
+ message << QString();
+
+ message << d->title << options;
QDBusPendingCall pendingCall = QDBusConnection::sessionBus().asyncCall(message);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pendingCall);