diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-03-10 10:13:33 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-03-15 15:02:58 (GMT) |
commit | 761bccd408c72e1d1d10d6c69f9f1d01fff30a0c (patch) | |
tree | b94e1d15e9e3b5637675dbd8b59bdd72af09c011 /src/gui/kernel/qkeymapper_x11.cpp | |
parent | c63fe6fcfc83028419dd84d13d24e7cb1295ac7f (diff) | |
download | Qt-761bccd408c72e1d1d10d6c69f9f1d01fff30a0c.zip Qt-761bccd408c72e1d1d10d6c69f9f1d01fff30a0c.tar.gz Qt-761bccd408c72e1d1d10d6c69f9f1d01fff30a0c.tar.bz2 |
Improve keyboard layout detection on X11
When the keyboard configuration includes multiple layouts in separate
groups, the _XKB_RULES_NAME property lists the layouts separated by a
comma. Previously we did not handle this.
We query the current keyboard group on startup and monitor
XkbStateNotify events for group changes. The existing infrastructre
from QKeyMapper deals with sending the KeyboardLayoutChange event to
all toplevel windows already.
This change includes a bit of refactoring to put the XKB detection and
initialization in qapplication_x11.cpp and XKB opcode, eventbase, and
errorbase into qt_x11_p.h (like with the other extensions).
Task-number: QTBUG-3631
Reviewed-by: denis
Diffstat (limited to 'src/gui/kernel/qkeymapper_x11.cpp')
-rw-r--r-- | src/gui/kernel/qkeymapper_x11.cpp | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index d6d1042..428ac3e 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -248,22 +248,17 @@ qt_XTranslateKey(register QXCoreDesc *dpy, QKeyMapperPrivate::QKeyMapperPrivate() - : keyboardInputDirection(Qt::LeftToRight), useXKB(false) + : keyboardInputDirection(Qt::LeftToRight), xkb_currentGroup(0) { memset(&coreDesc, 0, sizeof(coreDesc)); #ifndef QT_NO_XKB - int opcode = -1; - int xkbEventBase = -1; - int xkbErrorBase = -1; - int xkblibMajor = XkbMajorVersion; - int xkblibMinor = XkbMinorVersion; - if (XkbQueryExtension(X11->display, &opcode, &xkbEventBase, &xkbErrorBase, &xkblibMajor, &xkblibMinor)) - useXKB = true; -#endif - -#if 0 - qDebug() << "useXKB =" << useXKB; + if (X11->use_xkb) { + // get the current group + XkbStateRec xkbState; + if (XkbGetState(X11->display, XkbUseCoreKbd, &xkbState) == Success) + xkb_currentGroup = xkbState.group; + } #endif } @@ -276,7 +271,7 @@ QKeyMapperPrivate::~QKeyMapperPrivate() QList<int> QKeyMapperPrivate::possibleKeys(QKeyEvent *event) { #ifndef QT_NO_XKB - if (useXKB) + if (X11->use_xkb) return possibleKeysXKB(event); #endif return possibleKeysCore(event); @@ -486,7 +481,7 @@ enum { void QKeyMapperPrivate::clearMappings() { #ifndef QT_NO_XKB - if (useXKB) { + if (X11->use_xkb) { // try to determine the layout name and input direction by reading the _XKB_RULES_NAMES property off // the root window QByteArray layoutName; @@ -515,8 +510,13 @@ void QKeyMapperPrivate::clearMappings() p += qstrlen(p) + 1; } while (p < end); - layoutName = QByteArray::fromRawData(names[2], qstrlen(names[2])); - variantName = QByteArray::fromRawData(names[3], qstrlen(names[3])); + // the layout names and variants are saved in the _XKB_RULES_NAMES property as a comma separated list + QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(','); + if (uint(xkb_currentGroup) < uint(layoutNames.count())) + layoutName = layoutNames.at(xkb_currentGroup); + QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(','); + if (uint(xkb_currentGroup) < uint(variantNames.count())) + variantName = variantNames.at(xkb_currentGroup); } // ### ??? @@ -574,7 +574,7 @@ void QKeyMapperPrivate::clearMappings() // look at the modifier mapping, and get the correct masks for alt, meta, super, hyper, and mode_switch #ifndef QT_NO_XKB - if (useXKB) { + if (X11->use_xkb) { XkbDescPtr xkbDesc = XkbGetMap(X11->display, XkbAllClientInfoMask, XkbUseCoreKbd); for (int i = xkbDesc->min_key_code; i < xkbDesc->max_key_code; ++i) { const uint mask = xkbDesc->map->modmap ? xkbDesc->map->modmap[i] : 0; |