Commit b32240b9 authored by Harald Sitter's avatar Harald Sitter 🏳️‍🌈
Browse files

add Request closing support to all rejectable dialogs

this ensures that the dialog goes away when the app disappears while the
dialog is still up (e.g. when ctrl-c'ing the app)

this simply refactors the existing Request code to correctly register on
the path and then emit the closerequest that gets routed to the ::reject
function of the dialog. for extra flexibility this is implemented as a
template such that the concrete type doesn't matter so long as it has a
reject slot.

BUG: 386385
parent d5f958e1
Pipeline #166925 passed with stage
in 1 minute and 23 seconds
......@@ -3,10 +3,12 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* SPDX-FileCopyrightText: 2017 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*/
#include "access.h"
#include "accessdialog.h"
#include "request.h"
#include "utils.h"
#include <QLoggingCategory>
......@@ -62,6 +64,7 @@ uint AccessPortal::AccessDialog(const QDBusObjectPath &handle,
accessDialog->createDialog();
Utils::setParentWindow(accessDialog->windowHandle(), parent_window);
Request::makeClosableDialogRequest(handle, accessDialog);
if (options.contains(QStringLiteral("modal"))) {
accessDialog->windowHandle()->setModality(options.value(QStringLiteral("modal")).toBool() ? Qt::WindowModal : Qt::NonModal);
}
......
......@@ -3,10 +3,12 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* SPDX-FileCopyrightText: 2016-2018 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*/
#include "appchooser.h"
#include "appchooserdialog.h"
#include "request.h"
#include "utils.h"
#include <QLoggingCategory>
......@@ -49,6 +51,7 @@ uint AppChooserPortal::ChooseApplication(const QDBusObjectPath &handle,
AppChooserDialog *appDialog = new AppChooserDialog(choices, latestChoice, itemName.toString(), options.value(QStringLiteral("content_type")).toString());
m_appChooserDialogs.insert(handle.path(), appDialog);
Utils::setParentWindow(appDialog->windowHandle(), parent_window);
Request::makeClosableDialogRequest(handle, appDialog);
int result = appDialog->exec();
......
......@@ -16,6 +16,7 @@
#include "dynamiclauncherdialog.h"
#include "portalicon.h"
#include "request.h"
#include "utils.h"
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeDynamicLauncher, "xdp-kde-dynamic-launcher")
......@@ -126,6 +127,7 @@ uint DynamicLauncherPortal::PrepareInstall(const QDBusObjectPath &handle,
DynamicLauncherDialog dialog(typeToTitle(launcherType), icon, name, optionalTarget ? QUrl(optionalTarget.value()) : QUrl());
dialog.windowHandle()->setModality(modal ? Qt::WindowModal : Qt::NonModal);
Utils::setParentWindow(dialog.windowHandle(), parent_window);
Request::makeClosableDialogRequest(handle, &dialog);
const bool result = dialog.exec();
......
......@@ -33,6 +33,7 @@
#include <KWindowConfig>
#include "fuse_interface.h"
#include "request.h"
#include <mobilefiledialog.h>
Q_LOGGING_CATEGORY(XdgDesktopPortalKdeFileChooser, "xdp-kde-file-chooser")
......@@ -328,6 +329,7 @@ uint FileChooserPortal::OpenFile(const QDBusObjectPath &handle,
dirDialog.winId(); // Trigger window creation
Utils::setParentWindow(&dirDialog, parent_window);
Request::makeClosableDialogRequest(handle, &dirDialog);
if (dirDialog.exec() != QDialog::Accepted) {
return 1;
......@@ -357,6 +359,7 @@ uint FileChooserPortal::OpenFile(const QDBusObjectPath &handle,
QScopedPointer<FileDialog, QScopedPointerDeleteLater> fileDialog(new FileDialog());
Utils::setParentWindow(fileDialog.data(), parent_window);
Request::makeClosableDialogRequest(handle, fileDialog.get());
fileDialog->setWindowTitle(title);
fileDialog->setModal(modalDialog);
KFile::Mode mode = directory ? KFile::Mode::Directory : multipleFiles ? KFile::Mode::Files : KFile::Mode::File;
......@@ -509,6 +512,7 @@ uint FileChooserPortal::SaveFile(const QDBusObjectPath &handle,
QScopedPointer<FileDialog, QScopedPointerDeleteLater> fileDialog(new FileDialog());
Utils::setParentWindow(fileDialog.data(), parent_window);
Request::makeClosableDialogRequest(handle, fileDialog.get());
fileDialog->setWindowTitle(title);
fileDialog->setModal(modalDialog);
fileDialog->m_fileWidget->setOperationMode(KFileWidget::Saving);
......
......@@ -50,17 +50,7 @@ void InhibitPortal::Inhibit(const QDBusObjectPath &handle, const QString &app_id
qCDebug(XdgDesktopPortalKdeInhibit) << "Inhibition error: " << reply.error().message();
} else {
QDBusConnection sessionBus = QDBusConnection::sessionBus();
Request *request = new Request(this, QStringLiteral("org.freedesktop.impl.portal.Inhibit"), QVariant(reply.value()));
if (sessionBus.registerVirtualObject(handle.path(), request, QDBusConnection::VirtualObjectRegisterOption::SubPath)) {
connect(request, &Request::closeRequested, [request, handle]() {
QDBusConnection::sessionBus().unregisterObject(handle.path());
request->deleteLater();
});
} else {
qCDebug(XdgDesktopPortalKdeInhibit) << sessionBus.lastError().message();
qCDebug(XdgDesktopPortalKdeInhibit) << "Failed to register request object with inhibition";
request->deleteLater();
}
new Request(handle, this, QStringLiteral("org.freedesktop.impl.portal.Inhibit"), QVariant(reply.value()));
}
});
}
......@@ -2,12 +2,14 @@
* SPDX-FileCopyrightText: 2016-2017 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2007, 2010 John Layt <john@layt.net>
* SPDX-FileCopyrightText: 2007 Alex Merry <huntedhacker@tiscali.co.uk>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*
* SPDX-License-Identifier: LGPL-2.0-or-later
*
*/
#include "print.h"
#include "request.h"
#include "utils.h"
#include <KProcess>
......@@ -507,6 +509,7 @@ uint PrintPortal::PreparePrint(const QDBusObjectPath &handle,
QPrintDialog *printDialog = new QPrintDialog(printer);
Utils::setParentWindow(printDialog, parent_window);
Request::makeClosableDialogRequest(handle, printDialog);
// Process options
if (options.contains(QStringLiteral("modal"))) {
......
......@@ -4,10 +4,12 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* SPDX-FileCopyrightText: 2018 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*/
#include "remotedesktop.h"
#include "remotedesktopdialog.h"
#include "request.h"
#include "session.h"
#include "utils.h"
#include "waylandintegration.h"
......@@ -117,6 +119,7 @@ uint RemoteDesktopPortal::Start(const QDBusObjectPath &handle,
QScopedPointer<RemoteDesktopDialog, QScopedPointerDeleteLater> remoteDesktopDialog(
new RemoteDesktopDialog(app_id, session->deviceTypes(), session->screenSharingEnabled(), session->multipleSources()));
Utils::setParentWindow(remoteDesktopDialog->windowHandle(), parent_window);
Request::makeClosableDialogRequest(handle, remoteDesktopDialog.get());
connect(session, &Session::closed, remoteDesktopDialog.data(), &RemoteDesktopDialog::reject);
......
......@@ -17,11 +17,22 @@
Q_LOGGING_CATEGORY(XdgRequestKdeRequest, "xdp-kde-request")
Request::Request(QObject *parent, const QString &portalName, const QVariant &data)
Request::Request(const QDBusObjectPath &handle, QObject *parent, const QString &portalName, const QVariant &data)
: QDBusVirtualObject(parent)
, m_data(data)
, m_portalName(portalName)
{
auto sessionBus = QDBusConnection::sessionBus();
if (sessionBus.registerVirtualObject(handle.path(), this, QDBusConnection::VirtualObjectRegisterOption::SubPath)) {
connect(this, &Request::closeRequested, this, [this, handle]() {
QDBusConnection::sessionBus().unregisterObject(handle.path());
deleteLater();
});
} else {
qCDebug(XdgRequestKdeRequest) << sessionBus.lastError().message();
qCDebug(XdgRequestKdeRequest) << "Failed to register request object for" << handle.path();
deleteLater();
}
}
Request::~Request()
......@@ -66,6 +77,8 @@ bool Request::handleMessage(const QDBusMessage &message, const QDBusConnection &
QDBusConnection::sessionBus().asyncCall(messageReply);
});
} else {
Q_EMIT closeRequested();
}
}
}
......
......@@ -4,6 +4,7 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* SPDX-FileCopyrightText: 2017 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*/
#ifndef XDG_DESKTOP_PORTAL_KDE_REQUEST_H
......@@ -12,16 +13,26 @@
#include <QDBusVirtualObject>
#include <QObject>
class QDBusObjectPath;
class Request : public QDBusVirtualObject
{
Q_OBJECT
public:
explicit Request(QObject *parent = nullptr, const QString &portalName = QString(), const QVariant &data = QVariant());
explicit Request(const QDBusObjectPath &handle, QObject *parent = nullptr, const QString &portalName = QString(), const QVariant &data = QVariant());
~Request() override;
bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) override;
QString introspect(const QString &path) const override;
template<class T>
static Request *makeClosableDialogRequest(const QDBusObjectPath &handle, T *dialogAndParent)
{
auto request = new Request(handle, dialogAndParent);
connect(request, &Request::closeRequested, dialogAndParent, &T::reject);
return request;
}
Q_SIGNALS:
void closeRequested();
......
......@@ -4,10 +4,12 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* SPDX-FileCopyrightText: 2018 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*/
#include "screencast.h"
#include "notificationinhibition.h"
#include "request.h"
#include "screenchooserdialog.h"
#include "session.h"
#include "utils.h"
......@@ -242,6 +244,7 @@ uint ScreenCastPortal::Start(const QDBusObjectPath &handle,
new ScreenChooserDialog(app_id, session->multipleSources(), SourceTypes(session->types())));
connect(session, &Session::closed, screenDialog.data(), &ScreenChooserDialog::reject);
Utils::setParentWindow(screenDialog->windowHandle(), parent_window);
Request::makeClosableDialogRequest(handle, screenDialog.get());
valid = screenDialog->exec();
if (valid) {
allowRestore = screenDialog->allowRestore();
......
......@@ -4,9 +4,11 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* SPDX-FileCopyrightText: 2018 Jan Grulich <jgrulich@redhat.com>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*/
#include "screenshot.h"
#include "request.h"
#include "screenshotdialog.h"
#include "utils.h"
......@@ -88,6 +90,7 @@ uint ScreenshotPortal::Screenshot(const QDBusObjectPath &handle,
QPointer<ScreenshotDialog> screenshotDialog = new ScreenshotDialog;
Utils::setParentWindow(screenshotDialog->windowHandle(), parent_window);
Request::makeClosableDialogRequest(handle, screenshotDialog.data());
const bool modal = options.value(QStringLiteral("modal"), false).toBool();
screenshotDialog->windowHandle()->setModality(modal ? Qt::WindowModal : Qt::NonModal);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment