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:
Takao Fujiwara 2015-09-16 19:33:25 +09:00
parent 0f2da655ac
commit 4954ad6dbc
2 changed files with 97 additions and 17 deletions

View File

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

View File

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