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 <lars.knoll@theqtcompany.com>
Reviewed-by: Nedim Hadzic <nedim.hadzic@pelagicore.com>
This commit is contained in:
Bernd Weimer 2015-03-23 11:53:16 +01:00
parent 3accdb8086
commit b46fe39d94
7 changed files with 29 additions and 41 deletions

View File

@ -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<QPlatformInputContext, QPlatformInputContextPlugin>(loader(), platform, paramList))
return ret;
QPlatformInputContext *ic = qLoadPlugin1<QPlatformInputContext, QPlatformInputContextPlugin>
(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

View File

@ -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();
};

View File

@ -47,6 +47,7 @@
#include "qcocoamimetypes.h"
#include "qcocoaaccessibility.h"
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatformaccessibility.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/qcoreapplication.h>
@ -286,9 +287,9 @@ QCocoaIntegration::QCocoaIntegration(const QStringList &paramList)
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;

View File

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

View File

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

View File

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

View File

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