summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/file_chooser_portal.cpp5
-rw-r--r--src/file_chooser_portal.h8
-rw-r--r--src/main.cpp20
-rw-r--r--src/portal_daemon.cpp114
-rw-r--r--src/portal_daemon.h73
-rw-r--r--src/portal_service.cpp108
-rw-r--r--src/portal_service.h109
8 files changed, 390 insertions, 52 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 34b4c02..8ca6297 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,13 +12,13 @@ include_directories(
${TDE_INCLUDE_DIR}
${TQT_INCLUDE_DIRS}
${DBUS_TQT_INCLUDE_DIRS}
- ${CMAKE_BINARY_DIR}/interfaces
+ ${CMAKE_BINARY_DIR}
)
link_directories(
${TQT_LIBRARY_DIRS}
${DBUS_TQT_LIBRARY_DIRS}
- ${CMAKE_BINARY_DIR}/interfaces
+ ${CMAKE_BINARY_DIR}
)
tde_add_executable(
@@ -26,6 +26,7 @@ tde_add_executable(
SOURCES
main.cpp
+ portal_daemon.cpp
portal_service.cpp
file_chooser_portal.cpp
diff --git a/src/file_chooser_portal.cpp b/src/file_chooser_portal.cpp
index 1d037ec..0a7b340 100644
--- a/src/file_chooser_portal.cpp
+++ b/src/file_chooser_portal.cpp
@@ -134,6 +134,11 @@ void TDEFileChooserPortal::handleMethodReply(const TQT_DBusMessage &reply)
m_connection.send(reply);
}
+bool TDEFileChooserPortal::handleSignalSend(const TQT_DBusMessage& reply) {
+ handleMethodReply(reply);
+ return true;
+}
+
bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options,
const TQT_DBusObjectPath& handle,
TQ_UINT32& response,
diff --git a/src/file_chooser_portal.h b/src/file_chooser_portal.h
index 375b7c8..ef7b43a 100644
--- a/src/file_chooser_portal.h
+++ b/src/file_chooser_portal.h
@@ -33,7 +33,7 @@
#include <tdefile.h>
// Portal
-#include "filechooserInterface.h"
+#include "interfaces/filechooserInterface.h"
struct FileDialogOpts
{
@@ -64,6 +64,8 @@ class TDEFileChooserPortal : public TQObject,
TDEFileChooserPortal(TQT_DBusConnection &connection);
virtual ~TDEFileChooserPortal();
+ static const TQString interface() { return "org.freedesktop.impl.portal.FileChooser"; }
+
protected:
virtual bool OpenFile(const TQT_DBusObjectPath& handle,
const TQString& app_id,
@@ -92,7 +94,9 @@ class TDEFileChooserPortal : public TQObject,
TQMap<TQString, TQT_DBusVariant> &results,
TQT_DBusError& error);
- virtual void handleMethodReply(const TQT_DBusMessage &reply);
+ virtual void handleMethodReply(const TQT_DBusMessage& reply);
+ virtual bool handleSignalSend(const TQT_DBusMessage& reply);
+
private:
TQT_DBusConnection m_connection;
diff --git a/src/main.cpp b/src/main.cpp
index 278d754..c9b9e30 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,17 +19,12 @@
Improvements and feedback are welcome!
*******************************************************************************/
-// TQt
-#include <tqdbusconnection.h>
-
// TDE
-#include <kuniqueapplication.h>
#include <tdeaboutdata.h>
#include <tdecmdlineargs.h>
-#include <tdelocale.h>
// Portal
-#include "portal_service.h"
+#include "portal_daemon.h"
static const char description[] = I18N_NOOP("TDE XDG desktop portal");
@@ -48,17 +43,8 @@ int main(int argc, char **argv)
if (!KUniqueApplication::start())
return 0;
- KUniqueApplication app;
-
- TQT_DBusConnection connection = TQT_DBusConnection::sessionBus();
- if (!connection.isConnected())
- tqFatal("Failed to connect to session bus!");
-
- if (!connection.requestName("org.freedesktop.impl.portal.desktop.tde"))
- tqFatal("Failed to register XDG portal service!");
-
- TDEPortalService portal(connection);
-
+ PortalDaemon app;
+ app.disableSessionManagement();
return app.exec();
}
diff --git a/src/portal_daemon.cpp b/src/portal_daemon.cpp
new file mode 100644
index 0000000..cc8615f
--- /dev/null
+++ b/src/portal_daemon.cpp
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ XDG desktop portal implementation for TDE
+ Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+
+ Partially based on code from kdbusnotification
+ Copyright © 2021 Emanoil Kotsev <deloptes@gmail.com>
+
+ This program or library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Improvements and feedback are welcome!
+*******************************************************************************/
+
+// TQt
+#include <tqtimer.h>
+
+// TDE
+#include <kdebug.h>
+
+// Portal
+#include "portal_daemon.h"
+#include "portal_daemon.moc"
+
+PortalDaemon::PortalDaemon()
+: KUniqueApplication(),
+ m_retryCount(0)
+{
+ connectDBus();
+}
+
+PortalDaemon::~PortalDaemon()
+{
+ disconnectDBus();
+}
+
+void PortalDaemon::connectDBus()
+{
+ if (d_desktop) disconnectDBus();
+
+ m_connection = TQT_DBusConnection::addConnection(
+ TQT_DBusConnection::SessionBus,
+ DBUS_PORTAL_SERVICE
+ );
+
+ if (m_connection.isConnected())
+ {
+ m_connection.connect(this, TQ_SLOT(slotDBusSignal(const TQT_DBusMessage&)));
+ if (m_connection.requestName(DBUS_PORTAL_SERVICE, TQT_DBusConnection::NoReplace))
+ {
+ m_connection.scheduleDispatch();
+ kdDebug() << "TDE portal service successfully registered." << endl;
+ return;
+ }
+ }
+
+ ++m_retryCount;
+ kdWarning() << "Failed to connect to DBus, retrying in "
+ << DBUS_RETRY_TIMEOUT << " secs "
+ << "(" << m_retryCount << "/" << DBUS_RETRY_COUNT << "tries)"
+ << endl;
+
+ if (m_retryCount < DBUS_RETRY_COUNT)
+ {
+ TQTimer::singleShot(DBUS_RETRY_TIMEOUT, this, TQ_SLOT(connectDBus()));
+ }
+}
+
+void PortalDaemon::disconnectDBus()
+{
+ ZAP(d_root)
+ ZAP(d_org)
+ ZAP(d_freedesktop)
+ ZAP(d_portal)
+ ZAP(d_desktop)
+
+ if (m_connection.isConnected())
+ {
+ m_connection.disconnect(this, TQ_SLOT(slotDBusSignal(const TQT_DBusMessage&)));
+ m_connection.closeConnection(DBUS_PORTAL_SERVICE);
+ }
+
+ m_retryCount = 0;
+}
+
+void PortalDaemon::slotDBusSignal(const TQT_DBusMessage &message)
+{
+ TQString serviceName = message[0].toString();
+ if (message.interface() == TQString("org.freedesktop.DBus") &&
+ message.member() == TQString("NameAcquired") &&
+ serviceName == DBUS_PORTAL_SERVICE)
+ {
+ kdDebug() << "Portal daemon acquired unique DBus name: "
+ << serviceName << endl;
+
+ d_root = new RootNodeService(m_connection);
+ d_org = new OrgNodeService(m_connection);
+ d_freedesktop = new FreeDesktopNodeService(m_connection);
+ d_portal = new PortalNodeService(m_connection);
+ d_desktop = new DesktopNodeService(m_connection);
+ }
+}
+
+// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file
diff --git a/src/portal_daemon.h b/src/portal_daemon.h
new file mode 100644
index 0000000..974f234
--- /dev/null
+++ b/src/portal_daemon.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ XDG desktop portal implementation for TDE
+ Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+
+ Partially based on code from kdbusnotification
+ Copyright © 2021 Emanoil Kotsev <deloptes@gmail.com>
+
+ This program or library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the License,
+ or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this library; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Improvements and feedback are welcome!
+*******************************************************************************/
+
+#ifndef __PORTAL_DAEMON_H
+#define __PORTAL_DAEMON_H
+
+// TQt
+#include <tqdbusconnection.h>
+#include <tqdbusmessage.h>
+
+// TDE
+#include <kuniqueapplication.h>
+
+// DBus
+#include "portal_service.h"
+
+// Defines
+#define DBUS_PORTAL_SERVICE "org.freedesktop.impl.portal.desktop.tde"
+#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
+
+ public:
+ PortalDaemon();
+ virtual ~PortalDaemon();
+
+ private:
+ void connectDBus();
+ void disconnectDBus();
+
+ private slots:
+ void slotDBusSignal(const TQT_DBusMessage&);
+
+ private:
+ RootNodeService *d_root;
+ OrgNodeService *d_org;
+ FreeDesktopNodeService *d_freedesktop;
+ PortalNodeService *d_portal;
+ DesktopNodeService *d_desktop;
+
+ TQT_DBusConnection m_connection;
+ uint m_retryCount;
+};
+
+#endif // __PORTAL_DAEMON_H
+
+// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file
diff --git a/src/portal_service.cpp b/src/portal_service.cpp
index 86baa63..4e0eae3 100644
--- a/src/portal_service.cpp
+++ b/src/portal_service.cpp
@@ -2,6 +2,9 @@
XDG desktop portal implementation for TDE
Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+ Partially based on code from kdbusnotification
+ Copyright © 2021 Emanoil Kotsev <deloptes@gmail.com>
+
This program or library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the License,
@@ -34,42 +37,97 @@
static const char *dbusObjectPath = "/org/freedesktop/portal/desktop";
static const char *dbusInterfaceRoot = "org.freedesktop.impl.portal";
-TDEPortalService::TDEPortalService(TQT_DBusConnection &connection)
-: m_connection(connection)
+DesktopNodeService::DesktopNodeService(TQT_DBusConnection &connection)
+: org::freedesktop::portal::desktopNode(),
+ m_connection(connection)
+{
+ m_interfaces.insert("org.freedesktop.DBus.Introspectable", this);
+
+ REGISTER_PORTAL(TDEFileChooserPortal)
+
+ registerObject(connection, dbusObjectPath);
+}
+
+DesktopNodeService::~DesktopNodeService()
+{
+ DESTROY_PORTAL(TDEFileChooserPortal)
+}
+
+TQT_DBusObjectBase* DesktopNodeService::createInterface(const TQString& iface)
+{
+ return (TQT_DBusObjectBase*) m_interfaces[iface];
+}
+
+// ----------------------------------------------------------------------------------------
+
+PortalNodeService::PortalNodeService(TQT_DBusConnection &connection)
+: DBusBaseNode(), m_connection(connection)
+{
+ addChildNode("desktop");
+ registerObject(m_connection, "/org/freedesktop/portal");
+}
+
+PortalNodeService::~PortalNodeService()
{
- if (!m_connection.registerObject(dbusObjectPath, this))
- kdFatal() << "Unable to register XDG desktop portal object " << dbusObjectPath << endl;
- else
- kdDebug() << "Registered XDG desktop portal object " << dbusObjectPath << endl;
}
-TDEPortalService::~TDEPortalService()
+TQT_DBusObjectBase* PortalNodeService::createInterface(const TQString& iface)
{
- m_connection.unregisterObject(dbusObjectPath);
+ return (TQT_DBusObjectBase*) m_interfaces[iface];
}
-TQT_DBusObjectBase* TDEPortalService::getPortalInterface(TQCString portal)
+// ----------------------------------------------------------------------------------------
+
+FreeDesktopNodeService::FreeDesktopNodeService(TQT_DBusConnection &connection)
+: DBusBaseNode(), m_connection(connection)
{
- if (portal == "FileChooser")
- return new TDEFileChooserPortal(m_connection);
+ addChildNode("portal");
+ registerObject(m_connection, "/org/freedesktop");
+}
- return nullptr;
+FreeDesktopNodeService::~FreeDesktopNodeService()
+{
+}
+
+TQT_DBusObjectBase* FreeDesktopNodeService::createInterface(const TQString& iface)
+{
+ return (TQT_DBusObjectBase*) m_interfaces[iface];
+}
+
+// ----------------------------------------------------------------------------------------
+
+OrgNodeService::OrgNodeService(TQT_DBusConnection &connection)
+: DBusBaseNode(), m_connection(connection)
+{
+ addChildNode("freedesktop");
+ registerObject(m_connection, "/org");
+}
+
+OrgNodeService::~OrgNodeService()
+{
+}
+
+TQT_DBusObjectBase* OrgNodeService::createInterface(const TQString& iface)
+{
+ return (TQT_DBusObjectBase*) m_interfaces[iface];
+}
+
+// ----------------------------------------------------------------------------------------
+
+RootNodeService::RootNodeService(TQT_DBusConnection &connection)
+: DBusBaseNode(), m_connection(connection)
+{
+ addChildNode("org");
+ registerObject(m_connection, "/");
+}
+
+RootNodeService::~RootNodeService()
+{
}
-bool TDEPortalService::handleMethodCall(const TQT_DBusMessage &message)
+TQT_DBusObjectBase* RootNodeService::createInterface(const TQString& iface)
{
- if (!message.interface().startsWith(dbusInterfaceRoot))
- return false;
-
- TQCString portal = message.interface().mid(TQString(dbusInterfaceRoot).length() + 1).local8Bit();
- TQT_DBusObjectBase *iface = getPortalInterface(portal);
- if (!iface)
- {
- kdWarning() << "Unsupported XDG portal requested: " << portal << endl;
- return false;
- }
-
- return delegateMethodCall(message, iface);
+ return (TQT_DBusObjectBase*) m_interfaces[iface];
}
// kate: replace-tabs true; tab-width 4; indent-width 4; \ No newline at end of file
diff --git a/src/portal_service.h b/src/portal_service.h
index 8e7c400..9e3b282 100644
--- a/src/portal_service.h
+++ b/src/portal_service.h
@@ -2,6 +2,9 @@
XDG desktop portal implementation for TDE
Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com>
+ Partially based on code from kdbusnotification
+ Copyright © 2021 Emanoil Kotsev <deloptes@gmail.com>
+
This program or library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the License,
@@ -26,20 +29,114 @@
#include <tqdbusconnection.h>
#include <tqdbusobject.h>
-class TDEFileChooserPortal;
+// DBus
+#include "interfaces/desktopNode.h"
+#include "interfaces/dbusbaseNode.h"
+
+#define REGISTER_PORTAL(klass) \
+ m_interfaces.insert(klass::interface(), new klass(connection));
+
+#define DESTROY_PORTAL(klass) \
+ delete m_interfaces[klass::interface()];
+
+/**
+ * DesktopNodeService
+ * Service : org.freedesktop.DBus.Introspectable
+ * Path : /org/freedesktop/portal/desktop
+ * Children : -
+ */
+class DesktopNodeService : public org::freedesktop::portal::desktopNode
+{
+ public:
+ DesktopNodeService(TQT_DBusConnection&);
+ ~DesktopNodeService();
+
+ protected:
+ virtual TQT_DBusObjectBase* createInterface(const TQString&);
+
+ private:
+ TQMap<TQString, TQT_DBusObjectBase*> m_interfaces;
+ TQT_DBusConnection m_connection;
+};
+
+/**
+ * PortalNodeService
+ * Service : -
+ * Path : /org/freedesktop/portal
+ * Children : Desktop
+ */
+class PortalNodeService : public DBusBaseNode
+{
+ public:
+ PortalNodeService(TQT_DBusConnection&);
+ ~PortalNodeService();
+
+ protected:
+ virtual TQT_DBusObjectBase* createInterface(const TQString&);
+
+ private:
+ TQMap<TQString, TQT_DBusObjectBase*> m_interfaces;
+ TQT_DBusConnection m_connection;
+};
+
+/**
+ * FreeDesktopNodeService
+ * Service : -
+ * Path : /org/freedesktop
+ * Children : portal
+ */
+class FreeDesktopNodeService : public DBusBaseNode
+{
+ public:
+ FreeDesktopNodeService(TQT_DBusConnection&);
+ ~FreeDesktopNodeService();
+
+ protected:
+ virtual TQT_DBusObjectBase* createInterface(const TQString&);
+
+ private:
+ TQMap<TQString, TQT_DBusObjectBase*> m_interfaces;
+ TQT_DBusConnection m_connection;
+};
+
+/**
+ * OrgNodeService
+ * Service : -
+ * Path : /org
+ * Children : freedesktop
+ */
+class OrgNodeService : public DBusBaseNode
+{
+ public:
+ OrgNodeService(TQT_DBusConnection&);
+ ~OrgNodeService();
+
+ protected:
+ virtual TQT_DBusObjectBase* createInterface(const TQString&);
+
+ private:
+ TQMap<TQString, TQT_DBusObjectBase*> m_interfaces;
+ TQT_DBusConnection m_connection;
+};
-class TDEPortalService : public TQT_DBusObjectBase
+/**
+ * RootNodeService
+ * Service : -
+ * Path : /
+ * Children : org
+ */
+class RootNodeService : public DBusBaseNode
{
public:
- TDEPortalService(TQT_DBusConnection &connection);
- ~TDEPortalService();
+ RootNodeService(TQT_DBusConnection&);
+ ~RootNodeService();
protected:
- bool handleMethodCall(const TQT_DBusMessage &message);
+ virtual TQT_DBusObjectBase* createInterface(const TQString&);
private:
+ TQMap<TQString, TQT_DBusObjectBase*> m_interfaces;
TQT_DBusConnection m_connection;
- TQT_DBusObjectBase* getPortalInterface(TQCString portal);
};
#endif // __DESTKOP_PORTAL_H