diff options
author | Ilya Fedin <fedin-ilja2010@ya.ru> | 2022-11-17 01:01:43 +0400 |
---|---|---|
committer | Ilya Fedin <fedin-ilja2010@ya.ru> | 2022-11-17 06:17:45 +0400 |
commit | 7ea689c613c77aba2fbb638804b449749de38dd8 (patch) | |
tree | 27ee192da08ad5fb374b9f19f89e12a36c29b6ae /src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp | |
parent | d9637d07816af472bd40bb8e6e9f63f1c48085fe (diff) |
Fix QIBusPlatformInputContext leaks
QIBusPlatformInputContext re-creates various objects on ibus restart,
but never deletes them.
Sometimes this leads to multiplied input
(the same character entered multiple times).
Pick-to: 6.4 6.2 5.15
Change-Id: I34a898bfe56b19f9d76752c649e3aa64c77ae11a
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp')
-rw-r--r-- | src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp index dc6a9ad17a..8c2a3a1e6e 100644 --- a/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.cpp @@ -26,6 +26,8 @@ #include <private/qguiapplication_p.h> #include <private/qxkbcommon_p.h> +#include <memory> + #include <sys/types.h> #include <signal.h> @@ -46,26 +48,28 @@ enum { debug = 0 }; class QIBusPlatformInputContextPrivate { + Q_DISABLE_COPY_MOVE(QIBusPlatformInputContextPrivate) public: QIBusPlatformInputContextPrivate(); ~QIBusPlatformInputContextPrivate() { - delete context; - delete bus; - delete portalBus; - delete connection; + // dereference QDBusConnection to actually disconnect + serviceWatcher.setConnection(QDBusConnection(QString())); + context = nullptr; + portalBus = nullptr; + bus = nullptr; + QDBusConnection::disconnectFromBus("QIBusProxy"_L1); } static QString getSocketPath(); - QDBusConnection *createConnection(); + void createConnection(); void initBus(); void createBusProxy(); - QDBusConnection *connection; - QIBusProxy *bus; - QIBusProxyPortal *portalBus; // bus and portalBus are alternative. - QIBusInputContextProxy *context; + std::unique_ptr<QIBusProxy> bus; + std::unique_ptr<QIBusProxyPortal> portalBus; // bus and portalBus are alternative. + std::unique_ptr<QIBusInputContextProxy> context; QDBusServiceWatcher serviceWatcher; bool usePortal; // return value of shouldConnectIbusPortal @@ -498,12 +502,12 @@ void QIBusPlatformInputContext::socketChanged(const QString &str) m_timer.stop(); - if (d->context) - disconnect(d->context); - if (d->bus && d->bus->isValid()) - disconnect(d->bus); - if (d->connection) - d->connection->disconnectFromBus("QIBusProxy"_L1); + // dereference QDBusConnection to actually disconnect + d->serviceWatcher.setConnection(QDBusConnection(QString())); + d->context = nullptr; + d->bus = nullptr; + d->busConnected = false; + QDBusConnection::disconnectFromBus("QIBusProxy"_L1); m_timer.start(100); } @@ -555,17 +559,17 @@ void QIBusPlatformInputContext::globalEngineChanged(const QString &engine_name) void QIBusPlatformInputContext::connectToContextSignals() { if (d->bus && d->bus->isValid()) { - connect(d->bus, SIGNAL(GlobalEngineChanged(QString)), this, SLOT(globalEngineChanged(QString))); + connect(d->bus.get(), SIGNAL(GlobalEngineChanged(QString)), this, SLOT(globalEngineChanged(QString))); } 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(ForwardKeyEvent(uint,uint,uint)), this, SLOT(forwardKeyEvent(uint,uint,uint))); - connect(d->context, SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint))); - connect(d->context, SIGNAL(RequireSurroundingText()), this, SLOT(surroundingTextRequired())); - connect(d->context, SIGNAL(HidePreeditText()), this, SLOT(hidePreeditText())); - connect(d->context, SIGNAL(ShowPreeditText()), this, SLOT(showPreeditText())); + connect(d->context.get(), SIGNAL(CommitText(QDBusVariant)), SLOT(commitText(QDBusVariant))); + connect(d->context.get(), SIGNAL(UpdatePreeditText(QDBusVariant,uint,bool)), this, SLOT(updatePreeditText(QDBusVariant,uint,bool))); + connect(d->context.get(), SIGNAL(ForwardKeyEvent(uint,uint,uint)), this, SLOT(forwardKeyEvent(uint,uint,uint))); + connect(d->context.get(), SIGNAL(DeleteSurroundingText(int,uint)), this, SLOT(deleteSurroundingText(int,uint))); + connect(d->context.get(), SIGNAL(RequireSurroundingText()), this, SLOT(surroundingTextRequired())); + connect(d->context.get(), SIGNAL(HidePreeditText()), this, SLOT(hidePreeditText())); + connect(d->context.get(), SIGNAL(ShowPreeditText()), this, SLOT(showPreeditText())); } } @@ -581,11 +585,7 @@ static bool shouldConnectIbusPortal() } QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate() - : connection(nullptr), - bus(nullptr), - portalBus(nullptr), - context(nullptr), - usePortal(shouldConnectIbusPortal()), + : usePortal(shouldConnectIbusPortal()), valid(false), busConnected(false), needsSurroundingText(false) @@ -609,22 +609,23 @@ QIBusPlatformInputContextPrivate::QIBusPlatformInputContextPrivate() void QIBusPlatformInputContextPrivate::initBus() { - connection = createConnection(); + createConnection(); busConnected = false; createBusProxy(); } void QIBusPlatformInputContextPrivate::createBusProxy() { - if (!connection || !connection->isConnected()) + QDBusConnection connection("QIBusProxy"_L1); + if (!connection.isConnected()) return; const char* ibusService = usePortal ? "org.freedesktop.portal.IBus" : "org.freedesktop.IBus"; QDBusReply<QDBusObjectPath> ic; if (usePortal) { - portalBus = new QIBusProxyPortal(QLatin1StringView(ibusService), - "/org/freedesktop/IBus"_L1, - *connection); + portalBus = std::make_unique<QIBusProxyPortal>(QLatin1StringView(ibusService), + "/org/freedesktop/IBus"_L1, + connection); if (!portalBus->isValid()) { qWarning("QIBusPlatformInputContext: invalid portal bus."); return; @@ -632,9 +633,9 @@ void QIBusPlatformInputContextPrivate::createBusProxy() ic = portalBus->CreateInputContext("QIBusInputContext"_L1); } else { - bus = new QIBusProxy(QLatin1StringView(ibusService), - "/org/freedesktop/IBus"_L1, - *connection); + bus = std::make_unique<QIBusProxy>(QLatin1StringView(ibusService), + "/org/freedesktop/IBus"_L1, + connection); if (!bus->isValid()) { qWarning("QIBusPlatformInputContext: invalid bus."); return; @@ -644,7 +645,7 @@ void QIBusPlatformInputContextPrivate::createBusProxy() } serviceWatcher.removeWatchedService(ibusService); - serviceWatcher.setConnection(*connection); + serviceWatcher.setConnection(connection); serviceWatcher.addWatchedService(ibusService); if (!ic.isValid()) { @@ -652,7 +653,7 @@ void QIBusPlatformInputContextPrivate::createBusProxy() return; } - context = new QIBusInputContextProxy(QLatin1StringView(ibusService), ic.value().path(), *connection); + context = std::make_unique<QIBusInputContextProxy>(QLatin1StringView(ibusService), ic.value().path(), connection); if (!context->isValid()) { qWarning("QIBusPlatformInputContext: invalid input context."); @@ -714,14 +715,16 @@ QString QIBusPlatformInputContextPrivate::getSocketPath() u'-' + QString::fromLocal8Bit(host) + u'-' + QString::fromLocal8Bit(displayNumber); } -QDBusConnection *QIBusPlatformInputContextPrivate::createConnection() +void QIBusPlatformInputContextPrivate::createConnection() { - if (usePortal) - return new QDBusConnection(QDBusConnection::connectToBus(QDBusConnection::SessionBus, "QIBusProxy"_L1)); - QFile file(getSocketPath()); + if (usePortal) { + QDBusConnection::connectToBus(QDBusConnection::SessionBus, "QIBusProxy"_L1); + return; + } + QFile file(getSocketPath()); if (!file.open(QFile::ReadOnly)) - return nullptr; + return; QByteArray address; int pid = -1; @@ -740,9 +743,9 @@ QDBusConnection *QIBusPlatformInputContextPrivate::createConnection() if (debug) qDebug() << "IBUS_ADDRESS=" << address << "PID=" << pid; if (address.isEmpty() || pid < 0 || kill(pid, 0) != 0) - return nullptr; + return; - return new QDBusConnection(QDBusConnection::connectToBus(QString::fromLatin1(address), "QIBusProxy"_L1)); + QDBusConnection::connectToBus(QString::fromLatin1(address), "QIBusProxy"_L1); } QT_END_NAMESPACE |