mirror of
https://invent.kde.org/network/falkon.git
synced 2024-11-11 01:22:10 +01:00
QtSingleApplication: Add DBus backend for Linux
It should be more reliable than lockfile. BUG: 404494 FIXED-IN: 3.1.0
This commit is contained in:
parent
1553ab3c1b
commit
102bd219b7
|
@ -44,6 +44,11 @@
|
|||
#include <QDataStream>
|
||||
#include <QTime>
|
||||
|
||||
#include "../config.h"
|
||||
#if defined(Q_OS_LINUX) && !defined(DISABLE_DBUS)
|
||||
#define USE_DBUS
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <QLibrary>
|
||||
#include <qt_windows.h>
|
||||
|
@ -65,6 +70,33 @@ namespace QtLP_Private {
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_DBUS
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusAbstractAdaptor>
|
||||
|
||||
class QtSingleAppDBusInterface : public QDBusAbstractAdaptor
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_CLASSINFO("D-Bus Interface", "org.kde.QtSingleApplication")
|
||||
|
||||
public:
|
||||
explicit QtSingleAppDBusInterface(QObject *parent)
|
||||
: QDBusAbstractAdaptor(parent)
|
||||
{
|
||||
}
|
||||
|
||||
public Q_SLOTS:
|
||||
void SendMessage(const QString &message)
|
||||
{
|
||||
Q_EMIT messageReceived(message);
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void messageReceived(const QString &message);
|
||||
};
|
||||
#endif
|
||||
|
||||
const char* QtLocalPeer::ack = "ack";
|
||||
|
||||
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
||||
|
@ -100,18 +132,36 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
|||
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
|
||||
#endif
|
||||
|
||||
#ifdef USE_DBUS
|
||||
if (!QDBusConnection::sessionBus().isConnected()) {
|
||||
qCritical("Failed to connect to session bus!");
|
||||
}
|
||||
m_dbusRegistered = QDBusConnection::sessionBus().registerService(id);
|
||||
if (m_dbusRegistered) {
|
||||
QtSingleAppDBusInterface *iface = new QtSingleAppDBusInterface(this);
|
||||
connect(iface, &QtSingleAppDBusInterface::messageReceived, this, &QtLocalPeer::messageReceived);
|
||||
QDBusConnection::sessionBus().registerObject(QStringLiteral("/"), this);
|
||||
}
|
||||
#else
|
||||
server = new QLocalServer(this);
|
||||
QString lockName = QDir(QDir::tempPath()).absolutePath()
|
||||
+ QLatin1Char('/') + socketName
|
||||
+ QLatin1String("-lockfile");
|
||||
lockFile.setFileName(lockName);
|
||||
lockFile.open(QIODevice::ReadWrite);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool QtLocalPeer::isClient()
|
||||
{
|
||||
#ifdef USE_DBUS
|
||||
if (m_dbusRegistered) {
|
||||
return false;
|
||||
}
|
||||
return QDBusConnection::sessionBus().interface()->isServiceRegistered(id).value();
|
||||
#else
|
||||
if (lockFile.isLocked())
|
||||
return false;
|
||||
|
||||
|
@ -130,6 +180,7 @@ bool QtLocalPeer::isClient()
|
|||
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,6 +189,13 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
|
|||
if (!isClient())
|
||||
return false;
|
||||
|
||||
#ifdef USE_DBUS
|
||||
QDBusMessage msg = QDBusMessage::createMethodCall(id, QStringLiteral("/"),
|
||||
QStringLiteral("org.kde.QtSingleApplication"),
|
||||
QStringLiteral("SendMessage"));
|
||||
msg << message;
|
||||
return QDBusConnection::sessionBus().call(msg, QDBus::Block, timeout).type() == QDBusMessage::ReplyMessage;
|
||||
#else
|
||||
QLocalSocket socket;
|
||||
bool connOk = false;
|
||||
for(int i = 0; i < 2; i++) {
|
||||
|
@ -167,15 +225,19 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
|
|||
res &= (socket.read(qstrlen(ack)) == ack);
|
||||
}
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
void QtLocalPeer::removeLockedFile()
|
||||
{
|
||||
#ifndef USE_DBUS
|
||||
lockFile.remove();
|
||||
#endif
|
||||
}
|
||||
|
||||
void QtLocalPeer::receiveConnection()
|
||||
{
|
||||
#ifndef USE_DBUS
|
||||
QLocalSocket* socket = server->nextPendingConnection();
|
||||
if (!socket)
|
||||
return;
|
||||
|
@ -214,4 +276,7 @@ void QtLocalPeer::receiveConnection()
|
|||
socket->waitForDisconnected(1000); // make sure client reads ack
|
||||
delete socket;
|
||||
emit messageReceived(message); //### (might take a long time to return)
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "qtlocalpeer.moc"
|
||||
|
|
|
@ -73,6 +73,7 @@ protected:
|
|||
|
||||
private:
|
||||
static const char* ack;
|
||||
bool m_dbusRegistered = false;
|
||||
};
|
||||
|
||||
#endif // QTLOCALPEER_H
|
||||
|
|
|
@ -223,14 +223,14 @@ MainApplication::MainApplication(int &argc, char** argv)
|
|||
|
||||
// Don't start single application in private browsing
|
||||
if (!isPrivate()) {
|
||||
QString appId = QStringLiteral("FalkonWebBrowser");
|
||||
QString appId = QStringLiteral("org.kde.Falkon");
|
||||
|
||||
if (isPortable()) {
|
||||
appId.append(QLatin1String("Portable"));
|
||||
appId.append(QLatin1String(".Portable"));
|
||||
}
|
||||
|
||||
if (isTestModeEnabled()) {
|
||||
appId.append(QSL("TestMode"));
|
||||
appId.append(QSL(".TestMode"));
|
||||
}
|
||||
|
||||
if (newInstance) {
|
||||
|
@ -241,7 +241,7 @@ MainApplication::MainApplication(int &argc, char** argv)
|
|||
// Generate unique appId so it is possible to start more separate instances
|
||||
// of the same profile. It is dangerous to run more instances of the same profile,
|
||||
// but if the user wants it, we should allow it.
|
||||
appId.append(startProfile + QString::number(QDateTime::currentMSecsSinceEpoch()));
|
||||
appId.append(QLatin1Char('.') + startProfile + QString::number(QDateTime::currentMSecsSinceEpoch()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user