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>
This commit is contained in:
parent
f3cd571687
commit
c142fd8f68
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user