Qt IBus plugin connects to IBus Bus again if ibus-daemon does not run
Qt5 applications do not enable IBus when the applications are saved in the session and launched automatically in the next login. This patch checks the IBus socket path and connect to the bus when it's available. Task-number QTBUG-47657 Change-Id: I0883eaa2438fd27455da93f78f392ea3c1abe6b8 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This commit is contained in:
parent
0f2da655ac
commit
4954ad6dbc
@ -73,13 +73,18 @@ public:
|
|||||||
delete connection;
|
delete connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString getSocketPath();
|
||||||
static QDBusConnection *createConnection();
|
static QDBusConnection *createConnection();
|
||||||
|
|
||||||
|
void initBus();
|
||||||
|
void createBusProxy();
|
||||||
|
|
||||||
QDBusConnection *connection;
|
QDBusConnection *connection;
|
||||||
QIBusProxy *bus;
|
QIBusProxy *bus;
|
||||||
QIBusInputContextProxy *context;
|
QIBusInputContextProxy *context;
|
||||||
|
|
||||||
bool valid;
|
bool valid;
|
||||||
|
bool busConnected;
|
||||||
QString predit;
|
QString predit;
|
||||||
bool needsSurroundingText;
|
bool needsSurroundingText;
|
||||||
};
|
};
|
||||||
@ -88,12 +93,21 @@ public:
|
|||||||
QIBusPlatformInputContext::QIBusPlatformInputContext ()
|
QIBusPlatformInputContext::QIBusPlatformInputContext ()
|
||||||
: d(new QIBusPlatformInputContextPrivate())
|
: d(new QIBusPlatformInputContextPrivate())
|
||||||
{
|
{
|
||||||
if (d->context) {
|
QString socketPath = QIBusPlatformInputContextPrivate::getSocketPath();
|
||||||
connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant)));
|
QFile file(socketPath);
|
||||||
connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool)));
|
if (file.open(QFile::ReadOnly)) {
|
||||||
connect(d->context, SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint)));
|
// If KDE session save is used or restart ibus-daemon,
|
||||||
connect(d->context, SIGNAL(RequireSurroundingText()), this, SLOT(surroundingTextRequired()));
|
// the applications could run before ibus-daemon runs.
|
||||||
|
// We watch the getSocketPath() to get the launching ibus-daemon.
|
||||||
|
m_socketWatcher.addPath(socketPath);
|
||||||
|
connect(&m_socketWatcher, SIGNAL(fileChanged(QString)), this, SLOT(socketChanged(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_timer.setSingleShot(true);
|
||||||
|
connect(&m_timer, SIGNAL(timeout()), this, SLOT(connectToBus()));
|
||||||
|
|
||||||
|
connectToContextSignals();
|
||||||
|
|
||||||
QInputMethod *p = qApp->inputMethod();
|
QInputMethod *p = qApp->inputMethod();
|
||||||
connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged()));
|
connect(p, SIGNAL(cursorRectangleChanged()), this, SLOT(cursorRectChanged()));
|
||||||
m_eventFilterUseSynchronousMode = false;
|
m_eventFilterUseSynchronousMode = false;
|
||||||
@ -117,7 +131,7 @@ bool QIBusPlatformInputContext::isValid() const
|
|||||||
|
|
||||||
void QIBusPlatformInputContext::invokeAction(QInputMethod::Action a, int)
|
void QIBusPlatformInputContext::invokeAction(QInputMethod::Action a, int)
|
||||||
{
|
{
|
||||||
if (!d->valid)
|
if (!d->busConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (a == QInputMethod::Click)
|
if (a == QInputMethod::Click)
|
||||||
@ -128,7 +142,7 @@ void QIBusPlatformInputContext::reset()
|
|||||||
{
|
{
|
||||||
QPlatformInputContext::reset();
|
QPlatformInputContext::reset();
|
||||||
|
|
||||||
if (!d->valid)
|
if (!d->busConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
d->context->Reset();
|
d->context->Reset();
|
||||||
@ -139,7 +153,7 @@ void QIBusPlatformInputContext::commit()
|
|||||||
{
|
{
|
||||||
QPlatformInputContext::commit();
|
QPlatformInputContext::commit();
|
||||||
|
|
||||||
if (!d->valid)
|
if (!d->busConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QObject *input = qApp->focusObject();
|
QObject *input = qApp->focusObject();
|
||||||
@ -193,7 +207,7 @@ void QIBusPlatformInputContext::update(Qt::InputMethodQueries q)
|
|||||||
|
|
||||||
void QIBusPlatformInputContext::cursorRectChanged()
|
void QIBusPlatformInputContext::cursorRectChanged()
|
||||||
{
|
{
|
||||||
if (!d->valid)
|
if (!d->busConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QRect r = qApp->inputMethod()->cursorRectangle().toRect();
|
QRect r = qApp->inputMethod()->cursorRectangle().toRect();
|
||||||
@ -211,7 +225,7 @@ void QIBusPlatformInputContext::cursorRectChanged()
|
|||||||
|
|
||||||
void QIBusPlatformInputContext::setFocusObject(QObject *object)
|
void QIBusPlatformInputContext::setFocusObject(QObject *object)
|
||||||
{
|
{
|
||||||
if (!d->valid)
|
if (!d->busConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -291,7 +305,7 @@ void QIBusPlatformInputContext::deleteSurroundingText(int offset, uint n_chars)
|
|||||||
|
|
||||||
bool QIBusPlatformInputContext::filterEvent(const QEvent *event)
|
bool QIBusPlatformInputContext::filterEvent(const QEvent *event)
|
||||||
{
|
{
|
||||||
if (!d->valid)
|
if (!d->busConnected)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!inputMethodAccepted())
|
if (!inputMethodAccepted())
|
||||||
@ -398,12 +412,65 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
|
|||||||
call->deleteLater();
|
call->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QIBusPlatformInputContext::socketChanged(const QString &str)
|
||||||
|
{
|
||||||
|
qCDebug(qtQpaInputMethods) << "socketChanged";
|
||||||
|
Q_UNUSED (str);
|
||||||
|
|
||||||
|
m_timer.stop();
|
||||||
|
|
||||||
|
if (d->context)
|
||||||
|
disconnect(d->context);
|
||||||
|
if (d->connection)
|
||||||
|
d->connection->disconnectFromBus(QLatin1String("QIBusProxy"));
|
||||||
|
|
||||||
|
m_timer.start(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// When getSocketPath() is modified, the bus is not established yet
|
||||||
|
// so use m_timer.
|
||||||
|
void QIBusPlatformInputContext::connectToBus()
|
||||||
|
{
|
||||||
|
qCDebug(qtQpaInputMethods) << "QIBusPlatformInputContext::connectToBus";
|
||||||
|
d->initBus();
|
||||||
|
connectToContextSignals();
|
||||||
|
|
||||||
|
if (m_socketWatcher.files().size() == 0)
|
||||||
|
m_socketWatcher.addPath(QIBusPlatformInputContextPrivate::getSocketPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIBusPlatformInputContext::connectToContextSignals()
|
||||||
|
{
|
||||||
|
if (d->context) {
|
||||||
|
connect(d->context, SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant)));
|
||||||
|
connect(d->context, SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool)));
|
||||||
|
connect(d->context, SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint)));
|
||||||
|
connect(d->context, SIGNAL(RequireSurroundingText()), this, SLOT(surroundingTextRequired()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
|
QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
|
||||||
: connection(createConnection()),
|
: connection(0),
|
||||||
bus(0),
|
bus(0),
|
||||||
context(0),
|
context(0),
|
||||||
valid(false),
|
valid(false),
|
||||||
|
busConnected(false),
|
||||||
needsSurroundingText(false)
|
needsSurroundingText(false)
|
||||||
|
{
|
||||||
|
valid = !QStandardPaths::findExecutable(QString::fromLocal8Bit("ibus-daemon"), QStringList()).isEmpty();
|
||||||
|
if (!valid)
|
||||||
|
return;
|
||||||
|
initBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIBusPlatformInputContextPrivate::initBus()
|
||||||
|
{
|
||||||
|
connection = createConnection();
|
||||||
|
busConnected = false;
|
||||||
|
createBusProxy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIBusPlatformInputContextPrivate::createBusProxy()
|
||||||
{
|
{
|
||||||
if (!connection || !connection->isConnected())
|
if (!connection || !connection->isConnected())
|
||||||
return;
|
return;
|
||||||
@ -440,11 +507,11 @@ QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
|
|||||||
context->SetCapabilities(IBUS_CAP_PREEDIT_TEXT|IBUS_CAP_FOCUS|IBUS_CAP_SURROUNDING_TEXT);
|
context->SetCapabilities(IBUS_CAP_PREEDIT_TEXT|IBUS_CAP_FOCUS|IBUS_CAP_SURROUNDING_TEXT);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug(">>>> valid!");
|
qDebug(">>>> bus connected!");
|
||||||
valid = true;
|
busConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
|
QString QIBusPlatformInputContextPrivate::getSocketPath()
|
||||||
{
|
{
|
||||||
QByteArray display(qgetenv("DISPLAY"));
|
QByteArray display(qgetenv("DISPLAY"));
|
||||||
QByteArray host = "unix";
|
QByteArray host = "unix";
|
||||||
@ -462,9 +529,14 @@ QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
|
|||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << "host=" << host << "displayNumber" << displayNumber;
|
qDebug() << "host=" << host << "displayNumber" << displayNumber;
|
||||||
|
|
||||||
QFile file(QDir::homePath() + QLatin1String("/.config/ibus/bus/") +
|
return QDir::homePath() + QLatin1String("/.config/ibus/bus/") +
|
||||||
QLatin1String(QDBusConnection::localMachineId()) +
|
QLatin1String(QDBusConnection::localMachineId()) +
|
||||||
QLatin1Char('-') + QString::fromLocal8Bit(host) + QLatin1Char('-') + QString::fromLocal8Bit(displayNumber));
|
QLatin1Char('-') + QString::fromLocal8Bit(host) + QLatin1Char('-') + QString::fromLocal8Bit(displayNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
|
||||||
|
{
|
||||||
|
QFile file(getSocketPath());
|
||||||
|
|
||||||
if (!file.open(QFile::ReadOnly))
|
if (!file.open(QFile::ReadOnly))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -37,7 +37,9 @@
|
|||||||
|
|
||||||
#include <QtCore/qpointer.h>
|
#include <QtCore/qpointer.h>
|
||||||
#include <QtDBus/qdbuspendingreply.h>
|
#include <QtDBus/qdbuspendingreply.h>
|
||||||
|
#include <QFileSystemWatcher>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
#include <QTimer>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -96,10 +98,16 @@ public Q_SLOTS:
|
|||||||
void deleteSurroundingText(int offset, uint n_chars);
|
void deleteSurroundingText(int offset, uint n_chars);
|
||||||
void surroundingTextRequired();
|
void surroundingTextRequired();
|
||||||
void filterEventFinished(QDBusPendingCallWatcher *call);
|
void filterEventFinished(QDBusPendingCallWatcher *call);
|
||||||
|
void socketChanged(const QString &str);
|
||||||
|
void connectToBus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QIBusPlatformInputContextPrivate *d;
|
QIBusPlatformInputContextPrivate *d;
|
||||||
bool m_eventFilterUseSynchronousMode;
|
bool m_eventFilterUseSynchronousMode;
|
||||||
|
QFileSystemWatcher m_socketWatcher;
|
||||||
|
QTimer m_timer;
|
||||||
|
|
||||||
|
void connectToContextSignals();
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
Reference in New Issue
Block a user