Code reorganization and some improvements borrowed from kdbusnotification

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

@ -12,13 +12,13 @@ include_directories(
${TDE_INCLUDE_DIR} ${TDE_INCLUDE_DIR}
${TQT_INCLUDE_DIRS} ${TQT_INCLUDE_DIRS}
${DBUS_TQT_INCLUDE_DIRS} ${DBUS_TQT_INCLUDE_DIRS}
${CMAKE_BINARY_DIR}/interfaces ${CMAKE_BINARY_DIR}
) )
link_directories( link_directories(
${TQT_LIBRARY_DIRS} ${TQT_LIBRARY_DIRS}
${DBUS_TQT_LIBRARY_DIRS} ${DBUS_TQT_LIBRARY_DIRS}
${CMAKE_BINARY_DIR}/interfaces ${CMAKE_BINARY_DIR}
) )
tde_add_executable( tde_add_executable(
@ -26,6 +26,7 @@ tde_add_executable(
SOURCES SOURCES
main.cpp main.cpp
portal_daemon.cpp
portal_service.cpp portal_service.cpp
file_chooser_portal.cpp file_chooser_portal.cpp

@ -134,6 +134,11 @@ void TDEFileChooserPortal::handleMethodReply(const TQT_DBusMessage &reply)
m_connection.send(reply); m_connection.send(reply);
} }
bool TDEFileChooserPortal::handleSignalSend(const TQT_DBusMessage& reply) {
handleMethodReply(reply);
return true;
}
bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options, bool TDEFileChooserPortal::execFileDialog(FileDialogOpts options,
const TQT_DBusObjectPath& handle, const TQT_DBusObjectPath& handle,
TQ_UINT32& response, TQ_UINT32& response,

@ -33,7 +33,7 @@
#include <tdefile.h> #include <tdefile.h>
// Portal // Portal
#include "filechooserInterface.h" #include "interfaces/filechooserInterface.h"
struct FileDialogOpts struct FileDialogOpts
{ {
@ -64,6 +64,8 @@ class TDEFileChooserPortal : public TQObject,
TDEFileChooserPortal(TQT_DBusConnection &connection); TDEFileChooserPortal(TQT_DBusConnection &connection);
virtual ~TDEFileChooserPortal(); virtual ~TDEFileChooserPortal();
static const TQString interface() { return "org.freedesktop.impl.portal.FileChooser"; }
protected: protected:
virtual bool OpenFile(const TQT_DBusObjectPath& handle, virtual bool OpenFile(const TQT_DBusObjectPath& handle,
const TQString& app_id, const TQString& app_id,
@ -93,6 +95,8 @@ class TDEFileChooserPortal : public TQObject,
TQT_DBusError& error); 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: private:
TQT_DBusConnection m_connection; TQT_DBusConnection m_connection;

@ -19,17 +19,12 @@
Improvements and feedback are welcome! Improvements and feedback are welcome!
*******************************************************************************/ *******************************************************************************/
// TQt
#include <tqdbusconnection.h>
// TDE // TDE
#include <kuniqueapplication.h>
#include <tdeaboutdata.h> #include <tdeaboutdata.h>
#include <tdecmdlineargs.h> #include <tdecmdlineargs.h>
#include <tdelocale.h>
// Portal // Portal
#include "portal_service.h" #include "portal_daemon.h"
static const char description[] = I18N_NOOP("TDE XDG desktop portal"); static const char description[] = I18N_NOOP("TDE XDG desktop portal");
@ -48,17 +43,8 @@ int main(int argc, char **argv)
if (!KUniqueApplication::start()) if (!KUniqueApplication::start())
return 0; return 0;
KUniqueApplication app; PortalDaemon app;
app.disableSessionManagement();
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);
return app.exec(); return app.exec();
} }

@ -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;

@ -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;

@ -2,6 +2,9 @@
XDG desktop portal implementation for TDE XDG desktop portal implementation for TDE
Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com> 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 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 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, 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 *dbusObjectPath = "/org/freedesktop/portal/desktop";
static const char *dbusInterfaceRoot = "org.freedesktop.impl.portal"; static const char *dbusInterfaceRoot = "org.freedesktop.impl.portal";
TDEPortalService::TDEPortalService(TQT_DBusConnection &connection) DesktopNodeService::DesktopNodeService(TQT_DBusConnection &connection)
: m_connection(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)
{ {
if (!m_connection.registerObject(dbusObjectPath, this)) return (TQT_DBusObjectBase*) m_interfaces[iface];
kdFatal() << "Unable to register XDG desktop portal object " << dbusObjectPath << endl;
else
kdDebug() << "Registered XDG desktop portal object " << dbusObjectPath << endl;
} }
TDEPortalService::~TDEPortalService() // ----------------------------------------------------------------------------------------
PortalNodeService::PortalNodeService(TQT_DBusConnection &connection)
: DBusBaseNode(), m_connection(connection)
{ {
m_connection.unregisterObject(dbusObjectPath); addChildNode("desktop");
registerObject(m_connection, "/org/freedesktop/portal");
} }
TQT_DBusObjectBase* TDEPortalService::getPortalInterface(TQCString portal) PortalNodeService::~PortalNodeService()
{ {
if (portal == "FileChooser") }
return new TDEFileChooserPortal(m_connection);
return nullptr; TQT_DBusObjectBase* PortalNodeService::createInterface(const TQString& iface)
{
return (TQT_DBusObjectBase*) m_interfaces[iface];
} }
bool TDEPortalService::handleMethodCall(const TQT_DBusMessage &message) // ----------------------------------------------------------------------------------------
FreeDesktopNodeService::FreeDesktopNodeService(TQT_DBusConnection &connection)
: DBusBaseNode(), m_connection(connection)
{ {
if (!message.interface().startsWith(dbusInterfaceRoot)) addChildNode("portal");
return false; registerObject(m_connection, "/org/freedesktop");
}
TQCString portal = message.interface().mid(TQString(dbusInterfaceRoot).length() + 1).local8Bit(); FreeDesktopNodeService::~FreeDesktopNodeService()
TQT_DBusObjectBase *iface = getPortalInterface(portal);
if (!iface)
{ {
kdWarning() << "Unsupported XDG portal requested: " << portal << endl;
return false;
} }
return delegateMethodCall(message, iface); 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()
{
}
TQT_DBusObjectBase* RootNodeService::createInterface(const TQString& iface)
{
return (TQT_DBusObjectBase*) m_interfaces[iface];
} }
// kate: replace-tabs true; tab-width 4; indent-width 4; // kate: replace-tabs true; tab-width 4; indent-width 4;

@ -2,6 +2,9 @@
XDG desktop portal implementation for TDE XDG desktop portal implementation for TDE
Copyright © 2024 Mavridis Philippe <mavridisf@gmail.com> 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 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 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, published by the Free Software Foundation; either version 2.1 of the License,
@ -26,20 +29,114 @@
#include <tqdbusconnection.h> #include <tqdbusconnection.h>
#include <tqdbusobject.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: public:
TDEPortalService(TQT_DBusConnection &connection); RootNodeService(TQT_DBusConnection&);
~TDEPortalService(); ~RootNodeService();
protected: protected:
bool handleMethodCall(const TQT_DBusMessage &message); virtual TQT_DBusObjectBase* createInterface(const TQString&);
private: private:
TQMap<TQString, TQT_DBusObjectBase*> m_interfaces;
TQT_DBusConnection m_connection; TQT_DBusConnection m_connection;
TQT_DBusObjectBase* getPortalInterface(TQCString portal);
}; };
#endif // __DESTKOP_PORTAL_H #endif // __DESTKOP_PORTAL_H

Loading…
Cancel
Save