diff options
Diffstat (limited to 'src/compositor/compositor_api/qwaylandkeyboard.cpp')
-rw-r--r-- | src/compositor/compositor_api/qwaylandkeyboard.cpp | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp index b9377c85..93e2fbe9 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.cpp +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -67,6 +67,7 @@ QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandInputDevice *seat) , group() , pendingKeymap(false) #ifndef QT_NO_WAYLAND_XKB + , keymap_fd(-1) , xkb_state(0) #endif { @@ -276,42 +277,58 @@ void QWaylandKeyboardPrivate::initXKB() createXKBKeymap(); } -void QWaylandKeyboardPrivate::createXKBKeymap() -{ - if (!xkb_context) - return; - - if (xkb_state) - xkb_state_unref(xkb_state); - - struct xkb_rule_names rule_names = { strdup(qPrintable(keymap.rules())), - strdup(qPrintable(keymap.model())), - strdup(qPrintable(keymap.layout())), - strdup(qPrintable(keymap.variant())), - strdup(qPrintable(keymap.options())) }; - struct xkb_keymap *keymap = xkb_keymap_new_from_names(xkb_context, &rule_names, static_cast<xkb_keymap_compile_flags>(0)); +void QWaylandKeyboardPrivate::createXKBState(xkb_keymap *keymap) +{ char *keymap_str = xkb_keymap_get_as_string(keymap, XKB_KEYMAP_FORMAT_TEXT_V1); - if (!keymap_str) - qFatal("Failed to compile global XKB keymap"); + if (!keymap_str) { + qWarning("Failed to compile global XKB keymap"); + return; + } keymap_size = strlen(keymap_str) + 1; + if (keymap_fd >= 0) + close(keymap_fd); keymap_fd = createAnonymousFile(keymap_size); - if (keymap_fd < 0) - qFatal("Failed to create anonymous file of size %lu", static_cast<unsigned long>(keymap_size)); + if (keymap_fd < 0) { + qWarning("Failed to create anonymous file of size %lu", static_cast<unsigned long>(keymap_size)); + return; + } keymap_area = static_cast<char *>(mmap(0, keymap_size, PROT_READ | PROT_WRITE, MAP_SHARED, keymap_fd, 0)); if (keymap_area == MAP_FAILED) { close(keymap_fd); - qFatal("Failed to map shared memory segment"); + keymap_fd = -1; + qWarning("Failed to map shared memory segment"); + return; } strcpy(keymap_area, keymap_str); free(keymap_str); + if (xkb_state) + xkb_state_unref(xkb_state); xkb_state = xkb_state_new(keymap); +} - xkb_keymap_unref(keymap); +void QWaylandKeyboardPrivate::createXKBKeymap() +{ + if (!xkb_context) + return; + + struct xkb_rule_names rule_names = { strdup(qPrintable(keymap.rules())), + strdup(qPrintable(keymap.model())), + strdup(qPrintable(keymap.layout())), + strdup(qPrintable(keymap.variant())), + strdup(qPrintable(keymap.options())) }; + struct xkb_keymap *keymap = xkb_keymap_new_from_names(xkb_context, &rule_names, static_cast<xkb_keymap_compile_flags>(0)); + + if (keymap) { + createXKBState(keymap); + xkb_keymap_unref(keymap); + } else { + qWarning("Failed to load the '%s' XKB keymap.", qPrintable(this->keymap.layout())); + } free((char *)rule_names.rules); free((char *)rule_names.model); @@ -398,14 +415,13 @@ void QWaylandKeyboard::setKeymap(const QWaylandKeymap &keymap) { Q_D(QWaylandKeyboard); d->keymap = keymap; + d->pendingKeymap = true; // If there is no key currently pressed, update right away the keymap // Otherwise, delay the update when keys are released // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html if (d->keys.isEmpty()) { d->updateKeymap(); - } else { - d->pendingKeymap = true; } } |