From 2adc06f9406ec2f8c02d1619c73f384eb2947498 Mon Sep 17 00:00:00 2001 From: Robin Lee Date: Wed, 27 Jun 2018 11:54:20 +0800 Subject: IBus: Support the portal, needed for Flatpak environment Following commit 35ce6247 in IBus, IBus input plugin now connects to session bus and use IBus portal to create input context when running in Flatpak environment or IBUS_USE_PORTAL is set. [ChangeLog][plugins][ibus] Support IBus portal. Qt programs in Flatpak environment can now trigger IBus input method. Change-Id: I561f5f873d709b8abeae554d804daa058f9f6e16 Reviewed-by: Lars Knoll Reviewed-by: Takao Fujiwara --- src/plugins/platforminputcontexts/ibus/ibus.pro | 2 + .../interfaces/org.freedesktop.IBus.Portal.xml | 10 ++++ .../ibus/qibusplatforminputcontext.cpp | 64 ++++++++++++++++++---- .../ibus/qibusproxyportal.cpp | 26 +++++++++ .../platforminputcontexts/ibus/qibusproxyportal.h | 49 +++++++++++++++++ 5 files changed, 140 insertions(+), 11 deletions(-) create mode 100644 src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml create mode 100644 src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp create mode 100644 src/plugins/platforminputcontexts/ibus/qibusproxyportal.h (limited to 'src/plugins') diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro index 9f6c848e6a..52836bb8b6 100644 --- a/src/plugins/platforminputcontexts/ibus/ibus.pro +++ b/src/plugins/platforminputcontexts/ibus/ibus.pro @@ -3,12 +3,14 @@ TARGET = ibusplatforminputcontextplugin QT += dbus gui-private SOURCES += $$PWD/qibusplatforminputcontext.cpp \ $$PWD/qibusproxy.cpp \ + $$PWD/qibusproxyportal.cpp \ $$PWD/qibusinputcontextproxy.cpp \ $$PWD/qibustypes.cpp \ $$PWD/main.cpp HEADERS += $$PWD/qibusplatforminputcontext.h \ $$PWD/qibusproxy.h \ + $$PWD/qibusproxyportal.h \ $$PWD/qibusinputcontextproxy.h \ $$PWD/qibustypes.h diff --git a/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml new file mode 100644 index 0000000000..1a5414d0ae --- /dev/null +++ b/src/plugins/platforminputcontexts/ibus/interfaces/org.freedesktop.IBus.Portal.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index f339938f86..19f0afbf50 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -50,6 +50,7 @@ #include #include "qibusproxy.h" +#include "qibusproxyportal.h" #include "qibusinputcontextproxy.h" #include "qibustypes.h" @@ -78,19 +79,22 @@ 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; + bool usePortal; // return value of shouldConnectIbusPortal bool valid; bool busConnected; QString predit; @@ -507,6 +511,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; } @@ -572,15 +579,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 +629,35 @@ 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 ic; + if (usePortal) { + portalBus = new QIBusProxyPortal(QLatin1String(ibusService), + QLatin1String("/org/freedesktop/IBus"), + *connection); + if (!portalBus->isValid()) { + qWarning("QIBusPlatformInputContext: invalid portal bus."); + return; + } - QDBusReply ic = bus->CreateInputContext(QLatin1String("QIBusInputContext")); + 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")); + } 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 +705,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)) diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp new file mode 100644 index 0000000000..50482e2d9a --- /dev/null +++ b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.cpp @@ -0,0 +1,26 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -N -p qibusproxyportal -c QIBusProxyPortal interfaces/org.freedesktop.IBus.Portal.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * This file may have been hand-edited. Look for HAND-EDIT comments + * before re-generating it. + */ + +#include "qibusproxyportal.h" + +/* + * Implementation of interface class QIBusProxyPortal + */ + +QIBusProxyPortal::QIBusProxyPortal(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) + : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) +{ +} + +QIBusProxyPortal::~QIBusProxyPortal() +{ +} + diff --git a/src/plugins/platforminputcontexts/ibus/qibusproxyportal.h b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.h new file mode 100644 index 0000000000..bdd1d9c395 --- /dev/null +++ b/src/plugins/platforminputcontexts/ibus/qibusproxyportal.h @@ -0,0 +1,49 @@ +/* + * This file was generated by qdbusxml2cpp version 0.8 + * Command line was: qdbusxml2cpp -N -p qibusproxyportal -c QIBusProxyPortal interfaces/org.freedesktop.IBus.Portal.xml + * + * qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd. + * + * This is an auto-generated file. + * Do not edit! All changes made to it will be lost. + */ + +#ifndef QIBUSPROXYPORTAL_H +#define QIBUSPROXYPORTAL_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Proxy class for interface org.freedesktop.IBus.Portal + */ +class QIBusProxyPortal: public QDBusAbstractInterface +{ + Q_OBJECT +public: + static inline const char *staticInterfaceName() + { return "org.freedesktop.IBus.Portal"; } + +public: + QIBusProxyPortal(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = nullptr); + + ~QIBusProxyPortal(); + +public Q_SLOTS: // METHODS + inline QDBusPendingReply CreateInputContext(const QString &name) + { + QList argumentList; + argumentList << QVariant::fromValue(name); + return asyncCallWithArgumentList(QStringLiteral("CreateInputContext"), argumentList); + } + +Q_SIGNALS: // SIGNALS +}; + +#endif -- cgit v1.2.3