From c142fd8f686aa86e333cb3f30a4d3802155ecae5 Mon Sep 17 00:00:00 2001 From: David Redondo Date: Wed, 23 Feb 2022 11:12:17 +0100 Subject: 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 --- src/gui/platform/unix/qgenericunixservices.cpp | 40 +++++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'src/gui/platform/unix/qgenericunixservices.cpp') diff --git a/src/gui/platform/unix/qgenericunixservices.cpp b/src/gui/platform/unix/qgenericunixservices.cpp index a0e5466c588..54a0406cab3 100644 --- a/src/gui/platform/unix/qgenericunixservices.cpp +++ b/src/gui/platform/unix/qgenericunixservices.cpp @@ -3,6 +3,8 @@ #include "qgenericunixservices_p.h" #include +#include "qguiapplication.h" +#include "qwindow.h" #include #include @@ -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 -- cgit v1.2.3