summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qkeymapper_x11.cpp
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2010-03-10 10:13:33 (GMT)
committerBradley T. Hughes <bradley.hughes@nokia.com>2010-03-15 15:02:58 (GMT)
commit761bccd408c72e1d1d10d6c69f9f1d01fff30a0c (patch)
treeb94e1d15e9e3b5637675dbd8b59bdd72af09c011 /src/gui/kernel/qkeymapper_x11.cpp
parentc63fe6fcfc83028419dd84d13d24e7cb1295ac7f (diff)
downloadQt-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.cpp34
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;