diff options
author | Mavridis Philippe <mavridisf@gmail.com> | 2024-10-02 14:42:05 +0300 |
---|---|---|
committer | Mavridis Philippe <mavridisf@gmail.com> | 2024-10-02 14:42:05 +0300 |
commit | 2397c7e9cb9eba2b2b7934ef7d59e1bd3035c67d (patch) | |
tree | a2bab3537b3b0568797b7e1ca08055fd9f1c7453 | |
parent | acdd7db26e0808fc4d787fdec26e7f7479b1cb8f (diff) | |
download | xdg-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.xml | 2 | ||||
-rw-r--r-- | src/file_chooser_portal.cpp | 100 | ||||
-rw-r--r-- | src/file_chooser_portal.h | 42 | ||||
-rw-r--r-- | src/portal_daemon.cpp | 11 | ||||
-rw-r--r-- | src/portal_daemon.h | 2 | ||||
-rw-r--r-- | src/util.h | 2 |
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 @@ -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; |