FileDialog: Use Async methods and result sender thread

The thread waits until the non-modal dialog is done and then sends the result without
blocking the main thread. The dialog itself is initialized in the main thread.

This should fix high CPU usage while a dialog is open, not being able to open multiple
instances of a dialog at once and the DBus service locking down while a dialog is open.

xdg-desktop-portal-tde might yet make it into R14.1.3 ;-)

Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
pull/6/head
Mavridis Philippe 2 months ago
parent acdd7db26e
commit 2397c7e9cb
No known key found for this signature in database
GPG Key ID: F8D2D7E2F989A494

@ -28,6 +28,7 @@
<!-- FileChooser --> <!-- FileChooser -->
<interface name="org.freedesktop.impl.portal.FileChooser"> <interface name="org.freedesktop.impl.portal.FileChooser">
<method name="OpenFile"> <method name="OpenFile">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg name="handle" type="o" direction="in" /> <arg name="handle" type="o" direction="in" />
<arg name="app_id" type="s" direction="in" /> <arg name="app_id" type="s" direction="in" />
<arg name="parent_window" type="s" direction="in" /> <arg name="parent_window" type="s" direction="in" />
@ -37,6 +38,7 @@
<arg name="results" type="a{sv}" direction="out" /> <arg name="results" type="a{sv}" direction="out" />
</method> </method>
<method name="SaveFile"> <method name="SaveFile">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg name="handle" type="o" direction="in" /> <arg name="handle" type="o" direction="in" />
<arg name="app_id" type="s" direction="in" /> <arg name="app_id" type="s" direction="in" />
<arg name="parent_window" type="s" direction="in" /> <arg name="parent_window" type="s" direction="in" />

@ -22,6 +22,8 @@
// TQt // TQt
#include <tqregexp.h> #include <tqregexp.h>
#include <tqdbusobjectpath.h> #include <tqdbusobjectpath.h>
#include <tqapplication.h>
#include <tqthread.h>
// TDE // TDE
#include <tdeio/renamedlg.h> #include <tdeio/renamedlg.h>
@ -33,6 +35,48 @@
#include "file_chooser_portal.h" #include "file_chooser_portal.h"
#include "file_chooser_portal.moc" #include "file_chooser_portal.moc"
class DialogResultSender : public TQThread
{
public:
DialogResultSender(KFileDialog *dlg, int asyncCallId, TDEFileChooserPortal *portal, TQT_DBusAsyncCallback callback)
: TQThread(), m_dlg(dlg), m_asyncCallId(asyncCallId), m_portal(portal), m_callback(callback)
{}
~DialogResultSender()
{
wait();
}
void run()
{
if (!m_dlg) return;
while (m_dlg->isVisible())
{
usleep(1000);
}
KURL::List urllist = m_dlg->selectedURLs();
TQMap<TQString, TQT_DBusVariant> results;
TQT_DBusDataList urls = kurl_list_to_datalist(urllist);
TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant();
results.insert("uris", var);
TQ_UINT32 response = urllist.isEmpty() ? 1 : 0;
(m_portal->*m_callback)(m_asyncCallId, response, results);
m_dlg->deleteLater();
}
private:
KFileDialog *m_dlg;
int m_asyncCallId;
TDEFileChooserPortal *m_portal;
TQT_DBusAsyncCallback m_callback;
};
TDEFileChooserPortal::TDEFileChooserPortal(TQT_DBusConnection &connection) TDEFileChooserPortal::TDEFileChooserPortal(TQT_DBusConnection &connection)
: m_connection(connection) : m_connection(connection)
{} {}
@ -40,14 +84,12 @@ TDEFileChooserPortal::TDEFileChooserPortal(TQT_DBusConnection &connection)
TDEFileChooserPortal::~TDEFileChooserPortal() TDEFileChooserPortal::~TDEFileChooserPortal()
{} {}
bool TDEFileChooserPortal::OpenFile(const TQT_DBusObjectPath& handle, void TDEFileChooserPortal::OpenFileAsync(int asyncCallId,
const TQT_DBusObjectPath& handle,
const TQString& app_id, const TQString& app_id,
const TQString& parent_window, const TQString& parent_window,
const TQString& title, const TQString& title,
const TQMap<TQString, TQT_DBusVariant> &options, const TQT_DBusVariantMap &options)
TQ_UINT32& response,
TQMap<TQString, TQT_DBusVariant> &results,
TQT_DBusError& error)
{ {
FileDialogOpts opts; FileDialogOpts opts;
@ -70,17 +112,16 @@ bool TDEFileChooserPortal::OpenFile(const TQT_DBusObjectPath& handle,
opts.windowId = parse_window_id(parent_window); opts.windowId = parse_window_id(parent_window);
return execFileDialog(opts, handle, response, results, error); // Execute dialog
execFileDialog(&TDEFileChooserPortal::OpenFileAsyncReply, asyncCallId, opts, handle);
} }
bool TDEFileChooserPortal::SaveFile(const TQT_DBusObjectPath& handle, void TDEFileChooserPortal::SaveFileAsync(int asyncCallId,
const TQT_DBusObjectPath& handle,
const TQString& app_id, const TQString& app_id,
const TQString& parent_window, const TQString& parent_window,
const TQString& title, const TQString& title,
const TQMap<TQString, TQT_DBusVariant> &options, const TQT_DBusVariantMap &options)
TQ_UINT32& response,
TQMap<TQString, TQT_DBusVariant> &results,
TQT_DBusError& error)
{ {
FileDialogOpts opts; FileDialogOpts opts;
@ -109,7 +150,7 @@ bool TDEFileChooserPortal::SaveFile(const TQT_DBusObjectPath& handle,
opts.windowId = parse_window_id(parent_window); opts.windowId = parse_window_id(parent_window);
return execFileDialog(opts, handle, response, results, error); execFileDialog(&TDEFileChooserPortal::SaveFileAsyncReply, asyncCallId, opts, handle);
} }
bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle, bool TDEFileChooserPortal::SaveFiles(const TQT_DBusObjectPath& handle,
@ -211,11 +252,10 @@ bool TDEFileChooserPortal::handleSignalSend(const TQT_DBusMessage& reply) {
return true; return true;
} }
bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options, void TDEFileChooserPortal::execFileDialog(TQT_DBusAsyncCallback callback,
const TQT_DBusObjectPath& handle, int asyncCallId,
TQ_UINT32& response, FileDialogOpts options,
TQMap<TQString, TQT_DBusVariant> &results, const TQT_DBusObjectPath& handle)
TQT_DBusError& error)
{ {
KFileDialog *dialog = new KFileDialog(options.startDir, TQString::null, KFileDialog *dialog = new KFileDialog(options.startDir, TQString::null,
nullptr, "xdg-tde-file-chooser", nullptr, "xdg-tde-file-chooser",
@ -243,15 +283,11 @@ bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options,
if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId); if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId);
if (dialog->exec() == TQDialog::Accepted) // return dialog->selectedURLs();
{
response = 0; DialogResultSender *sender = new DialogResultSender(dialog, asyncCallId, this, callback);
TQT_DBusDataList urls = kurl_list_to_datalist(dialog->selectedURLs()); dialog->show();
TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant(); sender->start();
results.insert("uris", var);
}
else response = 1;
return true;
} }
TQString TDEFileChooserPortal::parseFilter(const TQT_DBusData data) TQString TDEFileChooserPortal::parseFilter(const TQT_DBusData data)

@ -29,6 +29,9 @@
#include "interfaces/filechooserInterface.h" #include "interfaces/filechooserInterface.h"
#include "interface.h" #include "interface.h"
class TDEFileChooserPortal;
typedef void(TDEFileChooserPortal::*TQT_DBusAsyncCallback)(int, TQ_UINT32, const TQT_DBusVariantMap&);
struct FileDialogOpts struct FileDialogOpts
{ {
TQString caption; TQString caption;
@ -61,23 +64,19 @@ class TDEFileChooserPortal : public TQObject,
virtual ~TDEFileChooserPortal(); virtual ~TDEFileChooserPortal();
protected: protected:
virtual bool OpenFile(const TQT_DBusObjectPath& handle, void OpenFileAsync(int asyncCallId,
const TQT_DBusObjectPath& handle,
const TQString& app_id, const TQString& app_id,
const TQString& parent_window, const TQString& parent_window,
const TQString& title, const TQString& title,
const TQT_DBusVariantMap &options, const TQT_DBusVariantMap &options);
TQ_UINT32& response,
TQT_DBusVariantMap &results,
TQT_DBusError& error);
virtual bool SaveFile(const TQT_DBusObjectPath& handle, void SaveFileAsync(int asyncCallId,
const TQT_DBusObjectPath& handle,
const TQString& app_id, const TQString& app_id,
const TQString& parent_window, const TQString& parent_window,
const TQString& title, const TQString& title,
const TQT_DBusVariantMap &options, const TQT_DBusVariantMap &options);
TQ_UINT32& response,
TQT_DBusVariantMap &results,
TQT_DBusError& error);
virtual bool SaveFiles(const TQT_DBusObjectPath& handle, virtual bool SaveFiles(const TQT_DBusObjectPath& handle,
const TQString& app_id, const TQString& app_id,
@ -99,11 +98,10 @@ class TDEFileChooserPortal : public TQObject,
TQString parseFilterList(const TQT_DBusVariant filterData, TQString parseFilterList(const TQT_DBusVariant filterData,
const TQT_DBusVariant currentFilterData); const TQT_DBusVariant currentFilterData);
bool execFileDialog(FileDialogOpts options, void execFileDialog(TQT_DBusAsyncCallback callback,
const TQT_DBusObjectPath& handle, int asyncCallId,
TQ_UINT32& response, FileDialogOpts options,
TQT_DBusVariantMap &results, const TQT_DBusObjectPath& handle);
TQT_DBusError& error);
}; };
#endif // __FILE_CHOOSER_PORTAL_H #endif // __FILE_CHOOSER_PORTAL_H

@ -31,6 +31,7 @@
// Portal // Portal
#include "portal_daemon.h" #include "portal_daemon.h"
#include "portal_daemon.moc" #include "portal_daemon.moc"
#include "util.h"
PortalDaemon::PortalDaemon() PortalDaemon::PortalDaemon()
: KUniqueApplication(), : KUniqueApplication(),
@ -83,11 +84,11 @@ void PortalDaemon::connectDBus()
void PortalDaemon::disconnectDBus() void PortalDaemon::disconnectDBus()
{ {
ZAP(d_root) DEL(d_root)
ZAP(d_org) DEL(d_org)
ZAP(d_freedesktop) DEL(d_freedesktop)
ZAP(d_portal) DEL(d_portal)
ZAP(d_desktop) DEL(d_desktop)
if (m_connection.isConnected()) if (m_connection.isConnected())
{ {

@ -40,8 +40,6 @@
#define DBUS_RETRY_TIMEOUT 5000 #define DBUS_RETRY_TIMEOUT 5000
#define DBUS_RETRY_COUNT 3 #define DBUS_RETRY_COUNT 3
#define ZAP(x) if (x) { delete x; x = nullptr; }
class PortalDaemon : public KUniqueApplication class PortalDaemon : public KUniqueApplication
{ {
TQ_OBJECT TQ_OBJECT

@ -31,6 +31,8 @@
// TDE // TDE
#include <kurl.h> #include <kurl.h>
#define DEL(x) if (x) { delete x; x = nullptr; }
typedef TQMap<TQString, TQT_DBusVariant> TQT_DBusVariantMap; typedef TQMap<TQString, TQT_DBusVariant> TQT_DBusVariantMap;
typedef TQValueList<TQT_DBusData> TQT_DBusValueList; typedef TQValueList<TQT_DBusData> TQT_DBusValueList;

Loading…
Cancel
Save