summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp')
-rw-r--r--src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp111
1 files changed, 90 insertions, 21 deletions
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
index f339938f86..0e587965ca 100644
--- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
+++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp
@@ -50,6 +50,7 @@
#include <qpa/qwindowsysteminterface.h>
#include "qibusproxy.h"
+#include "qibusproxyportal.h"
#include "qibusinputcontextproxy.h"
#include "qibustypes.h"
@@ -78,19 +79,23 @@ public:
{
delete context;
delete bus;
+ delete portalBus;
delete connection;
}
static QString getSocketPath();
- static QDBusConnection *createConnection();
+ QDBusConnection *createConnection();
void initBus();
void createBusProxy();
QDBusConnection *connection;
QIBusProxy *bus;
+ QIBusProxyPortal *portalBus; // bus and portalBus are alternative.
QIBusInputContextProxy *context;
+ QDBusServiceWatcher serviceWatcher;
+ bool usePortal; // return value of shouldConnectIbusPortal
bool valid;
bool busConnected;
QString predit;
@@ -103,20 +108,25 @@ public:
QIBusPlatformInputContext::QIBusPlatformInputContext ()
: d(new QIBusPlatformInputContextPrivate())
{
- QString socketPath = QIBusPlatformInputContextPrivate::getSocketPath();
- QFile file(socketPath);
- if (file.open(QFile::ReadOnly)) {
+ if (!d->usePortal) {
+ QString socketPath = QIBusPlatformInputContextPrivate::getSocketPath();
+ QFile file(socketPath);
+ if (file.open(QFile::ReadOnly)) {
#ifndef QT_NO_FILESYSTEMWATCHER
- // If KDE session save is used or restart ibus-daemon,
- // 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)));
+ qCDebug(qtQpaInputMethods) << "socketWatcher.addPath" << socketPath;
+ // If KDE session save is used or restart ibus-daemon,
+ // 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)));
#endif
+ }
+ m_timer.setSingleShot(true);
+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(connectToBus()));
}
- m_timer.setSingleShot(true);
- connect(&m_timer, SIGNAL(timeout()), this, SLOT(connectToBus()));
+ QObject::connect(&d->serviceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(busRegistered(QString)));
+ QObject::connect(&d->serviceWatcher, SIGNAL(serviceUnregistered(QString)), this, SLOT(busUnregistered(QString)));
connectToContextSignals();
@@ -507,6 +517,9 @@ void QIBusPlatformInputContext::filterEventFinished(QDBusPendingCallWatcher *cal
QLocale QIBusPlatformInputContext::locale() const
{
+ // d->locale is not updated when IBus portal is used
+ if (d->usePortal)
+ return QPlatformInputContext::locale();
return d->locale;
}
@@ -527,6 +540,22 @@ void QIBusPlatformInputContext::socketChanged(const QString &str)
m_timer.start(100);
}
+void QIBusPlatformInputContext::busRegistered(const QString &str)
+{
+ qCDebug(qtQpaInputMethods) << "busRegistered";
+ Q_UNUSED (str);
+ if (d->usePortal) {
+ connectToBus();
+ }
+}
+
+void QIBusPlatformInputContext::busUnregistered(const QString &str)
+{
+ qCDebug(qtQpaInputMethods) << "busUnregistered";
+ Q_UNUSED (str);
+ d->busConnected = false;
+}
+
// When getSocketPath() is modified, the bus is not established yet
// so use m_timer.
void QIBusPlatformInputContext::connectToBus()
@@ -536,7 +565,7 @@ void QIBusPlatformInputContext::connectToBus()
connectToContextSignals();
#ifndef QT_NO_FILESYSTEMWATCHER
- if (m_socketWatcher.files().size() == 0)
+ if (!d->usePortal && m_socketWatcher.files().size() == 0)
m_socketWatcher.addPath(QIBusPlatformInputContextPrivate::getSocketPath());
#endif
}
@@ -572,15 +601,34 @@ void QIBusPlatformInputContext::connectToContextSignals()
}
}
+static inline bool checkRunningUnderFlatpak()
+{
+ return !QStandardPaths::locate(QStandardPaths::RuntimeLocation, QLatin1String("flatpak-info")).isEmpty();
+}
+
+static bool shouldConnectIbusPortal()
+{
+ // honor the same env as ibus-gtk
+ return (checkRunningUnderFlatpak() || !qgetenv("IBUS_USE_PORTAL").isNull());
+}
+
QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate()
: connection(0),
bus(0),
+ portalBus(0),
context(0),
+ usePortal(shouldConnectIbusPortal()),
valid(false),
busConnected(false),
needsSurroundingText(false)
{
- valid = !QStandardPaths::findExecutable(QString::fromLocal8Bit("ibus-daemon"), QStringList()).isEmpty();
+ if (usePortal) {
+ valid = true;
+ if (debug)
+ qDebug() << "use IBus portal";
+ } else {
+ valid = !QStandardPaths::findExecutable(QString::fromLocal8Bit("ibus-daemon"), QStringList()).isEmpty();
+ }
if (!valid)
return;
initBus();
@@ -603,21 +651,40 @@ void QIBusPlatformInputContextPrivate::createBusProxy()
if (!connection || !connection->isConnected())
return;
- bus = new QIBusProxy(QLatin1String("org.freedesktop.IBus"),
- QLatin1String("/org/freedesktop/IBus"),
- *connection);
- if (!bus->isValid()) {
- qWarning("QIBusPlatformInputContext: invalid bus.");
- return;
+ const char* ibusService = usePortal ? "org.freedesktop.portal.IBus" : "org.freedesktop.IBus";
+ QDBusReply<QDBusObjectPath> ic;
+ if (usePortal) {
+ portalBus = new QIBusProxyPortal(QLatin1String(ibusService),
+ QLatin1String("/org/freedesktop/IBus"),
+ *connection);
+ if (!portalBus->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid portal bus.");
+ return;
+ }
+
+ ic = portalBus->CreateInputContext(QLatin1String("QIBusInputContext"));
+ } else {
+ bus = new QIBusProxy(QLatin1String(ibusService),
+ QLatin1String("/org/freedesktop/IBus"),
+ *connection);
+ if (!bus->isValid()) {
+ qWarning("QIBusPlatformInputContext: invalid bus.");
+ return;
+ }
+
+ ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
}
- QDBusReply<QDBusObjectPath> ic = bus->CreateInputContext(QLatin1String("QIBusInputContext"));
+ serviceWatcher.removeWatchedService(ibusService);
+ serviceWatcher.setConnection(*connection);
+ serviceWatcher.addWatchedService(ibusService);
+
if (!ic.isValid()) {
qWarning("QIBusPlatformInputContext: CreateInputContext failed.");
return;
}
- context = new QIBusInputContextProxy(QLatin1String("org.freedesktop.IBus"), ic.value().path(), *connection);
+ context = new QIBusInputContextProxy(QLatin1String(ibusService), ic.value().path(), *connection);
if (!context->isValid()) {
qWarning("QIBusPlatformInputContext: invalid input context.");
@@ -665,6 +732,8 @@ QString QIBusPlatformInputContextPrivate::getSocketPath()
QDBusConnection *QIBusPlatformInputContextPrivate::createConnection()
{
+ if (usePortal)
+ return new QDBusConnection(QDBusConnection::connectToBus(QDBusConnection::SessionBus, QLatin1String("QIBusProxy")));
QFile file(getSocketPath());
if (!file.open(QFile::ReadOnly))