From b46fe39d940712c5d401e731e171a7ccfadfe648 Mon Sep 17 00:00:00 2001 From: Bernd Weimer Date: Mon, 23 Mar 2015 11:53:16 +0100 Subject: [PATCH] Harmonize input context selection Input context selection works differently across platforms. On some platforms it is not possible to request a specific context at all (e.g. Wayland). This will be unified, depending on the environment variable "QT_IM_MODULE", you will get: - null: default (platform) context, if defined (otherwise no context) - empty: no context - set: set one, if it exists and is valid (otherwise no context) [ChangeLog][Platform Specific Changes] Haromnized input context selection. QT_IM_MODULE environment variable will be taken into account. Change-Id: Ic8f826fbc6ace25941cd19b9b086943e848fbe01 Reviewed-by: Lars Knoll Reviewed-by: Nedim Hadzic --- .../kernel/qplatforminputcontextfactory.cpp | 44 ++++++------------- .../kernel/qplatforminputcontextfactory_p.h | 1 + .../platforms/cocoa/qcocoaintegration.mm | 7 +-- .../platforms/windows/qwindowsintegration.cpp | 7 ++- src/plugins/platforms/xcb/qxcbconnection.cpp | 3 -- src/plugins/platforms/xcb/qxcbintegration.cpp | 5 ++- .../kernel/qinputmethod/tst_qinputmethod.cpp | 3 ++ 7 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/gui/kernel/qplatforminputcontextfactory.cpp b/src/gui/kernel/qplatforminputcontextfactory.cpp index a7660e76ae..9d55b778ce 100644 --- a/src/gui/kernel/qplatforminputcontextfactory.cpp +++ b/src/gui/kernel/qplatforminputcontextfactory.cpp @@ -56,48 +56,32 @@ QStringList QPlatformInputContextFactory::keys() #endif } +QString QPlatformInputContextFactory::requested() +{ + QByteArray env = qgetenv("QT_IM_MODULE"); + return env.isNull() ? QString() : QString::fromLocal8Bit(env); +} + QPlatformInputContext *QPlatformInputContextFactory::create(const QString& key) { +#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) QStringList paramList = key.split(QLatin1Char(':')); const QString platform = paramList.takeFirst().toLower(); -#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS) - if (QPlatformInputContext *ret = qLoadPlugin1(loader(), platform, paramList)) - return ret; + QPlatformInputContext *ic = qLoadPlugin1 + (loader(), platform, paramList); + if (ic && ic->isValid()) + return ic; + + delete ic; #endif return 0; } QPlatformInputContext *QPlatformInputContextFactory::create() { - QPlatformInputContext *ic = 0; - - QString icString = QString::fromLatin1(qgetenv("QT_IM_MODULE")); - - if (icString == QLatin1String("none")) - return 0; - - ic = create(icString); - if (ic && ic->isValid()) - return ic; - - delete ic; - ic = 0; - - QStringList k = keys(); - for (int i = 0; i < k.size(); ++i) { - if (k.at(i) == icString) - continue; - ic = create(k.at(i)); - if (ic && ic->isValid()) - return ic; - delete ic; - ic = 0; - } - - return 0; + return create(requested()); } - QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatforminputcontextfactory_p.h b/src/gui/kernel/qplatforminputcontextfactory_p.h index a74c4f5f80..38f4358287 100644 --- a/src/gui/kernel/qplatforminputcontextfactory_p.h +++ b/src/gui/kernel/qplatforminputcontextfactory_p.h @@ -56,6 +56,7 @@ class Q_GUI_EXPORT QPlatformInputContextFactory { public: static QStringList keys(); + static QString requested(); static QPlatformInputContext *create(const QString &key); static QPlatformInputContext *create(); }; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 2e6bfc95db..051a1c8710 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -47,6 +47,7 @@ #include "qcocoamimetypes.h" #include "qcocoaaccessibility.h" +#include #include #include #include @@ -286,9 +287,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) qWarning("Creating multiple Cocoa platform integrations is not supported"); mInstance = this; - mInputContext.reset(QPlatformInputContextFactory::create()); - if (mInputContext.isNull()) - mInputContext.reset(new QCocoaInputContext()); + QString icStr = QPlatformInputContextFactory::requested(); + icStr.isNull() ? mInputContext.reset(new QCocoaInputContext) + : mInputContext.reset(QPlatformInputContextFactory::create(icStr)); initResources(); QMacAutoReleasePool pool; diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index f97c23c207..bbb1f68a52 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -264,10 +264,9 @@ QWindowsIntegration::~QWindowsIntegration() void QWindowsIntegration::initialize() { - if (QPlatformInputContext *pluginContext = QPlatformInputContextFactory::create()) - d->m_inputContext.reset(pluginContext); - else - d->m_inputContext.reset(new QWindowsInputContext); + QString icStr = QPlatformInputContextFactory::requested(); + icStr.isNull() ? d->m_inputContext.reset(new QWindowsInputContext) + : d->m_inputContext.reset(QPlatformInputContextFactory::create(icStr)); } bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 15d3575e60..e612cff9a3 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -590,9 +590,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra qCDebug(QT_XCB_GLINTEGRATION) << "Failed to create xcb gl-integration"; sync(); - - if (qEnvironmentVariableIsEmpty("QT_IM_MODULE")) - qputenv("QT_IM_MODULE", QByteArray("compose")); } QXcbConnection::~QXcbConnection() diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp index fc06f1a7b0..9cedfa77ad 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -268,7 +268,10 @@ void QXcbIntegration::initialize() { // Perform everything that may potentially need the event dispatcher (timers, socket // notifiers) here instead of the constructor. - m_inputContext.reset(QPlatformInputContextFactory::create()); + QString icStr = QPlatformInputContextFactory::requested(); + if (icStr.isNull()) + icStr = QLatin1String("compose"); + m_inputContext.reset(QPlatformInputContextFactory::create(icStr)); } void QXcbIntegration::moveToScreen(QWindow *window, int screen) diff --git a/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp b/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp index a36e31e2e2..ab17edecb6 100644 --- a/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp +++ b/tests/auto/gui/kernel/qinputmethod/tst_qinputmethod.cpp @@ -292,6 +292,9 @@ void tst_qinputmethod::inputMethodAccepted() if (qApp->platformName().toLower() == QLatin1String("wayland")) QSKIP("Wayland: This fails. Figure out why."); + if (qApp->platformName().toLower() == QLatin1String("xcb")) + QSKIP("XCB: depends on dedicated platform context."); + InputItem disabledItem; disabledItem.setEnabled(false);