summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMavridis Philippe <mavridisf@gmail.com>2024-10-02 14:42:05 +0300
committerMavridis Philippe <mavridisf@gmail.com>2024-10-02 14:42:05 +0300
commit2397c7e9cb9eba2b2b7934ef7d59e1bd3035c67d (patch)
treea2bab3537b3b0568797b7e1ca08055fd9f1c7453
parentacdd7db26e0808fc4d787fdec26e7f7479b1cb8f (diff)
downloadxdg-desktop-portal-tde-2397c7e9cb9eba2b2b7934ef7d59e1bd3035c67d.tar.gz
xdg-desktop-portal-tde-2397c7e9cb9eba2b2b7934ef7d59e1bd3035c67d.zip
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>
-rw-r--r--interfaces/interfaces.xml2
-rw-r--r--src/file_chooser_portal.cpp100
-rw-r--r--src/file_chooser_portal.h42
-rw-r--r--src/portal_daemon.cpp11
-rw-r--r--src/portal_daemon.h2
-rw-r--r--src/util.h2
6 files changed, 98 insertions, 61 deletions
diff --git a/interfaces/interfaces.xml b/interfaces/interfaces.xml
index c6f5357..e86379f 100644
--- a/interfaces/interfaces.xml
+++ b/interfaces/interfaces.xml
@@ -28,6 +28,7 @@
<!-- FileChooser -->
<interface name="org.freedesktop.impl.portal.FileChooser">
<method name="OpenFile">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg name="handle" type="o" direction="in" />
<arg name="app_id" type="s" direction="in" />
<arg name="parent_window" type="s" direction="in" />
@@ -37,6 +38,7 @@
<arg name="results" type="a{sv}" direction="out" />
</method>
<method name="SaveFile">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg name="handle" type="o" direction="in" />
<arg name="app_id" type="s" direction="in" />
<arg name="parent_window" type="s" direction="in" />
diff --git a/src/file_chooser_portal.cpp b/src/file_chooser_portal.cpp
index 9b8f6e7..246ad1a 100644
--- a/src/file_chooser_portal.cpp
+++ b/src/file_chooser_portal.cpp
@@ -22,6 +22,8 @@
// TQt
#include <tqregexp.h>
#include <tqdbusobjectpath.h>
+#include <tqapplication.h>
+#include <tqthread.h>
// TDE
#include <tdeio/renamedlg.h>
@@ -33,6 +35,48 @@
#include "file_chooser_portal.h"
#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)
: m_connection(connection)
{}
@@ -40,14 +84,12 @@ TDEFileChooserPortal::TDEFileChooserPortal(TQT_DBusConnection &connection)
TDEFileChooserPortal::~TDEFileChooserPortal()
{}
-bool TDEFileChooserPortal::OpenFile(const TQT_DBusObjectPath& handle,
- const TQString& app_id,
- const TQString& parent_window,
- const TQString& title,
- const TQMap<TQString, TQT_DBusVariant> &options,
- TQ_UINT32& response,
- TQMap<TQString, TQT_DBusVariant> &results,
- TQT_DBusError& error)
+void TDEFileChooserPortal::OpenFileAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& parent_window,
+ const TQString& title,
+ const TQT_DBusVariantMap &options)
{
FileDialogOpts opts;
@@ -70,17 +112,16 @@ bool TDEFileChooserPortal::OpenFile(const TQT_DBusObjectPath& handle,
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,
- const TQString& app_id,
- const TQString& parent_window,
- const TQString& title,
- const TQMap<TQString, TQT_DBusVariant> &options,
- TQ_UINT32& response,
- TQMap<TQString, TQT_DBusVariant> &results,
- TQT_DBusError& error)
+void TDEFileChooserPortal::SaveFileAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& parent_window,
+ const TQString& title,
+ const TQT_DBusVariantMap &options)
{
FileDialogOpts opts;
@@ -109,7 +150,7 @@ bool TDEFileChooserPortal::SaveFile(const TQT_DBusObjectPath& handle,
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,
@@ -211,11 +252,10 @@ bool TDEFileChooserPortal::handleSignalSend(const TQT_DBusMessage& reply) {
return true;
}
-bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options,
- const TQT_DBusObjectPath& handle,
- TQ_UINT32& response,
- TQMap<TQString, TQT_DBusVariant> &results,
- TQT_DBusError& error)
+void TDEFileChooserPortal::execFileDialog(TQT_DBusAsyncCallback callback,
+ int asyncCallId,
+ FileDialogOpts options,
+ const TQT_DBusObjectPath& handle)
{
KFileDialog *dialog = new KFileDialog(options.startDir, TQString::null,
nullptr, "xdg-tde-file-chooser",
@@ -243,15 +283,11 @@ bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options,
if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId);
- if (dialog->exec() == TQDialog::Accepted)
- {
- response = 0;
- TQT_DBusDataList urls = kurl_list_to_datalist(dialog->selectedURLs());
- TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant();
- results.insert("uris", var);
- }
- else response = 1;
- return true;
+// return dialog->selectedURLs();
+
+ DialogResultSender *sender = new DialogResultSender(dialog, asyncCallId, this, callback);
+ dialog->show();
+ sender->start();
}
TQString TDEFileChooserPortal::parseFilter(const TQT_DBusData data)
diff --git a/src/file_chooser_portal.h b/src/file_chooser_portal.h
index 9732b8d..383d219 100644
--- a/src/file_chooser_portal.h
+++ b/src/file_chooser_portal.h
@@ -29,6 +29,9 @@
#include "interfaces/filechooserInterface.h"
#include "interface.h"
+class TDEFileChooserPortal;
+typedef void(TDEFileChooserPortal::*TQT_DBusAsyncCallback)(int, TQ_UINT32, const TQT_DBusVariantMap&);
+
struct FileDialogOpts
{
TQString caption;
@@ -61,23 +64,19 @@ class TDEFileChooserPortal : public TQObject,
virtual ~TDEFileChooserPortal();
protected:
- virtual bool OpenFile(const TQT_DBusObjectPath& handle,
- const TQString& app_id,
- const TQString& parent_window,
- const TQString& title,
- const TQT_DBusVariantMap &options,
- TQ_UINT32& response,
- TQT_DBusVariantMap &results,
- TQT_DBusError& error);
-
- virtual bool SaveFile(const TQT_DBusObjectPath& handle,
- const TQString& app_id,
- const TQString& parent_window,
- const TQString& title,
- const TQT_DBusVariantMap &options,
- TQ_UINT32& response,
- TQT_DBusVariantMap &results,
- TQT_DBusError& error);
+ void OpenFileAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& parent_window,
+ const TQString& title,
+ const TQT_DBusVariantMap &options);
+
+ void SaveFileAsync(int asyncCallId,
+ const TQT_DBusObjectPath& handle,
+ const TQString& app_id,
+ const TQString& parent_window,
+ const TQString& title,
+ const TQT_DBusVariantMap &options);
virtual bool SaveFiles(const TQT_DBusObjectPath& handle,
const TQString& app_id,
@@ -99,11 +98,10 @@ class TDEFileChooserPortal : public TQObject,
TQString parseFilterList(const TQT_DBusVariant filterData,
const TQT_DBusVariant currentFilterData);
- bool execFileDialog(FileDialogOpts options,
- const TQT_DBusObjectPath& handle,
- TQ_UINT32& response,
- TQT_DBusVariantMap &results,
- TQT_DBusError& error);
+ void execFileDialog(TQT_DBusAsyncCallback callback,
+ int asyncCallId,
+ FileDialogOpts options,
+ const TQT_DBusObjectPath& handle);
};
#endif // __FILE_CHOOSER_PORTAL_H
diff --git a/src/portal_daemon.cpp b/src/portal_daemon.cpp
index f533791..7b2749d 100644
--- a/src/portal_daemon.cpp
+++ b/src/portal_daemon.cpp
@@ -31,6 +31,7 @@
// Portal
#include "portal_daemon.h"
#include "portal_daemon.moc"
+#include "util.h"
PortalDaemon::PortalDaemon()
: KUniqueApplication(),
@@ -83,11 +84,11 @@ void PortalDaemon::connectDBus()
void PortalDaemon::disconnectDBus()
{
- ZAP(d_root)
- ZAP(d_org)
- ZAP(d_freedesktop)
- ZAP(d_portal)
- ZAP(d_desktop)
+ DEL(d_root)
+ DEL(d_org)
+ DEL(d_freedesktop)
+ DEL(d_portal)
+ DEL(d_desktop)
if (m_connection.isConnected())
{
diff --git a/src/portal_daemon.h b/src/portal_daemon.h
index 974f234..4b52612 100644
--- a/src/portal_daemon.h
+++ b/src/portal_daemon.h
@@ -40,8 +40,6 @@
#define DBUS_RETRY_TIMEOUT 5000
#define DBUS_RETRY_COUNT 3
-#define ZAP(x) if (x) { delete x; x = nullptr; }
-
class PortalDaemon : public KUniqueApplication
{
TQ_OBJECT
diff --git a/src/util.h b/src/util.h
index e5a2040..64df0ee 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,6 +31,8 @@
// TDE
#include <kurl.h>
+#define DEL(x) if (x) { delete x; x = nullptr; }
+
typedef TQMap<TQString, TQT_DBusVariant> TQT_DBusVariantMap;
typedef TQValueList<TQT_DBusData> TQT_DBusValueList;