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 <QDataStream>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
#if defined(Q_OS_LINUX) && !defined(DISABLE_DBUS)
|
||||||
|
#define USE_DBUS
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
|
@ -65,6 +70,33 @@ namespace QtLP_Private {
|
||||||
#endif
|
#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";
|
const char* QtLocalPeer::ack = "ack";
|
||||||
|
|
||||||
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
||||||
|
@ -100,18 +132,36 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
|
||||||
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
|
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
|
||||||
#endif
|
#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);
|
server = new QLocalServer(this);
|
||||||
QString lockName = QDir(QDir::tempPath()).absolutePath()
|
QString lockName = QDir(QDir::tempPath()).absolutePath()
|
||||||
+ QLatin1Char('/') + socketName
|
+ QLatin1Char('/') + socketName
|
||||||
+ QLatin1String("-lockfile");
|
+ QLatin1String("-lockfile");
|
||||||
lockFile.setFileName(lockName);
|
lockFile.setFileName(lockName);
|
||||||
lockFile.open(QIODevice::ReadWrite);
|
lockFile.open(QIODevice::ReadWrite);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool QtLocalPeer::isClient()
|
bool QtLocalPeer::isClient()
|
||||||
{
|
{
|
||||||
|
#ifdef USE_DBUS
|
||||||
|
if (m_dbusRegistered) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return QDBusConnection::sessionBus().interface()->isServiceRegistered(id).value();
|
||||||
|
#else
|
||||||
if (lockFile.isLocked())
|
if (lockFile.isLocked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -130,6 +180,7 @@ bool QtLocalPeer::isClient()
|
||||||
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
|
||||||
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,6 +189,13 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
|
||||||
if (!isClient())
|
if (!isClient())
|
||||||
return false;
|
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;
|
QLocalSocket socket;
|
||||||
bool connOk = false;
|
bool connOk = false;
|
||||||
for(int i = 0; i < 2; i++) {
|
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);
|
res &= (socket.read(qstrlen(ack)) == ack);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtLocalPeer::removeLockedFile()
|
void QtLocalPeer::removeLockedFile()
|
||||||
{
|
{
|
||||||
|
#ifndef USE_DBUS
|
||||||
lockFile.remove();
|
lockFile.remove();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtLocalPeer::receiveConnection()
|
void QtLocalPeer::receiveConnection()
|
||||||
{
|
{
|
||||||
|
#ifndef USE_DBUS
|
||||||
QLocalSocket* socket = server->nextPendingConnection();
|
QLocalSocket* socket = server->nextPendingConnection();
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return;
|
return;
|
||||||
|
@ -214,4 +276,7 @@ void QtLocalPeer::receiveConnection()
|
||||||
socket->waitForDisconnected(1000); // make sure client reads ack
|
socket->waitForDisconnected(1000); // make sure client reads ack
|
||||||
delete socket;
|
delete socket;
|
||||||
emit messageReceived(message); //### (might take a long time to return)
|
emit messageReceived(message); //### (might take a long time to return)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "qtlocalpeer.moc"
|
||||||
|
|
|
@ -73,6 +73,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char* ack;
|
static const char* ack;
|
||||||
|
bool m_dbusRegistered = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QTLOCALPEER_H
|
#endif // QTLOCALPEER_H
|
||||||
|
|
|
@ -223,14 +223,14 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||||
|
|
||||||
// Don't start single application in private browsing
|
// Don't start single application in private browsing
|
||||||
if (!isPrivate()) {
|
if (!isPrivate()) {
|
||||||
QString appId = QStringLiteral("FalkonWebBrowser");
|
QString appId = QStringLiteral("org.kde.Falkon");
|
||||||
|
|
||||||
if (isPortable()) {
|
if (isPortable()) {
|
||||||
appId.append(QLatin1String("Portable"));
|
appId.append(QLatin1String(".Portable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTestModeEnabled()) {
|
if (isTestModeEnabled()) {
|
||||||
appId.append(QSL("TestMode"));
|
appId.append(QSL(".TestMode"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newInstance) {
|
if (newInstance) {
|
||||||
|
@ -241,7 +241,7 @@ MainApplication::MainApplication(int &argc, char** argv)
|
||||||
// Generate unique appId so it is possible to start more separate instances
|
// 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,
|
// 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.
|
// 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