diff --git a/configure b/configure index 5ad29bb..7ff0df1 100644 --- a/configure +++ b/configure @@ -5060,10 +5060,8 @@ if [ "$CFG_XCB" != "no" ]; then QMAKE_LIBS_XCB="`$PKG_CONFIG --libs $XCB_PACKAGES 2>/dev/null`" fi - # libxcb version 1.10 was the first version that enables xcb-xkb by default, - # therefore the minimal xcb-xkb version we support is 1.10 CFG_XKB=no - if $PKG_CONFIG --exists "xcb-xkb >= 1.10" 2>/dev/null; then + if $PKG_CONFIG --exists "xcb-xkb" 2>/dev/null; then QMAKE_CFLAGS_XKB="`$PKG_CONFIG --cflags xcb xcb-xkb 2>/dev/null`" QMAKE_LIBS_XKB="`$PKG_CONFIG --libs xcb xcb-xkb 2>/dev/null`" if compileTest qpa/xcb-xkb "xcb-xkb" $QMAKE_CFLAGS_XKB $QMAKE_LIBS_XKB; then @@ -5172,16 +5170,16 @@ MIN_REQ_XKBCOMMON="0.4.1" if [ "$CFG_XCB" != "no" ]; then if [ "$CFG_XKBCOMMON" != "no" ] && [ "$CFG_XKBCOMMON" != "qt" ]; then # Check if there is a suitable system-wide xkbcommon - if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon xkbcommon-x11 >= $MIN_REQ_XKBCOMMON" 2>/dev/null; then - QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon xkbcommon-x11 2>/dev/null`" - QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon xkbcommon-x11 2>/dev/null`" + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists "xkbcommon >= $MIN_REQ_XKBCOMMON" 2>/dev/null; then + QMAKE_CFLAGS_XKBCOMMON="`$PKG_CONFIG --cflags xkbcommon 2>/dev/null`" + QMAKE_LIBS_XKBCOMMON="`$PKG_CONFIG --libs xkbcommon 2>/dev/null`" QMakeVar set QMAKE_CFLAGS_XKBCOMMON "$QMAKE_CFLAGS_XKBCOMMON" QMakeVar set QMAKE_LIBS_XKBCOMMON "$QMAKE_LIBS_XKBCOMMON" CFG_XKBCOMMON=system elif [ "$CFG_XKBCOMMON" = "system" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo " xkbcommon support cannot be enabled because either xkbcommon or " - echo " xkbcommon-x11 >= $MIN_REQ_XKBCOMMON was not found via pkg-config!" + echo " xkbcommon support cannot be enabled because xkbcommon" + echo " >= $MIN_REQ_XKBCOMMON was not found via pkg-config!" [ -z "$PKG_CONFIG" ] && echo " Use of pkg-config is not enabled, maybe you want to pass -force-pkg-config?" echo " Turn on verbose messaging (-v) to $0 to see the final report." echo " If you believe this message is in error you may use the continue" diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 5510c3b..4762977 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -1761,7 +1761,7 @@ void QXcbConnection::initializeXKB() xcb_xkb_use_extension_cookie_t xkb_query_cookie; xcb_xkb_use_extension_reply_t *xkb_query; - xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION); + xkb_query_cookie = xcb_xkb_use_extension(c, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION); xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0); if (!xkb_query) { diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 5fb7457..487c3ba 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -693,50 +693,65 @@ void QXcbKeyboard::updateKeymap() // log only critical errors, we do our own error logging from printKeymapError() xkb_context_set_log_level(xkb_context, (xkb_log_level)XKB_LOG_LEVEL_CRITICAL); } - // update xkb keymap object - xkb_keymap_unref(xkb_keymap); - xkb_keymap = 0; - struct xkb_state *new_state = 0; -#ifndef QT_NO_XKB - if (connection()->hasXKB()) { - xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, xcb_connection(), core_device_id, (xkb_keymap_compile_flags)0); - if (xkb_keymap) { - // Create a new keyboard state object for a keymap - new_state = xkb_x11_state_new_from_device(xkb_keymap, xcb_connection(), core_device_id); - } - } -#endif + readXKBConfig(); + // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names + if (xkb_keymap) + xkb_keymap_unref(xkb_keymap); + + xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); if (!xkb_keymap) { - // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names - readXKBConfig(); + // last fallback is to used hard-coded keymap name, see DEFAULT_XKB_* in xkbcommon.pri + qWarning() << "Qt: Could not determine keyboard configuration data" + " from X server, will use hard-coded keymap configuration."; + clearXKBConfig(); xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); - if (!xkb_keymap) { - // last fallback is to used hard-coded keymap name, see DEFAULT_XKB_* in xkbcommon.pri - qWarning() << "Qt: Could not determine keyboard configuration data" - " from X server, will use hard-coded keymap configuration."; - clearXKBConfig(); - xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0); - } - if (xkb_keymap) { - new_state = xkb_state_new(xkb_keymap); - } else { - printKeymapError("Qt: Failed to compile a keymap!"); - m_config = false; - return; - } - } + if (!xkb_keymap) { + printKeymapError("Qt: Failed to compile a keymap!"); + m_config = false; + return; + } + + struct xkb_state *new_state = xkb_state_new(xkb_keymap); if (!new_state) { qWarning("Qt: Failed to create xkb state!"); m_config = false; return; } - // update xkb state object - xkb_state_unref(xkb_state); - xkb_state = new_state; - if (!connection()->hasXKB()) - updateXKBMods(); + + if (xkb_state) { + xkb_state_unref(xkb_state); + xkb_state = new_state; + } else { + xkb_state = new_state; +#ifndef QT_NO_XKB + if (connection()->hasXKB()) { + // get initial state from the X server (and keep it up-to-date at all times) + xcb_xkb_get_state_cookie_t state; + xcb_xkb_get_state_reply_t *init_state; + + xcb_connection_t *c = xcb_connection(); + state = xcb_xkb_get_state(c, XCB_XKB_ID_USE_CORE_KBD); + init_state = xcb_xkb_get_state_reply(c, state, 0); + if (!init_state) { + qWarning("Qt: couldn't retrieve an initial keyboard state"); + return; + } + /* The xkb keyboard state is comprised of the state of all keyboard modifiers, + the keyboard group, and the state of the pointer buttons */ + xkb_state_update_mask(xkb_state, + init_state->baseMods, + init_state->latchedMods, + init_state->lockedMods, + init_state->baseGroup, + init_state->latchedGroup, + init_state->lockedGroup); + free(init_state); + } else +#endif + updateXKBMods(); + } checkForLatinLayout(); } @@ -1097,11 +1112,23 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection) if (connection->hasXKB()) { updateVModMapping(); updateVModToRModMapping(); - core_device_id = xkb_x11_get_core_keyboard_device_id(xcb_connection()); - if (core_device_id == -1) { + + // get the core keyboard id + xcb_xkb_get_device_info_cookie_t device_id_cookie; + xcb_xkb_get_device_info_reply_t *device_id; + + device_id_cookie = xcb_xkb_get_device_info(xcb_connection(), + XCB_XKB_ID_USE_CORE_KBD, + 0, 0, 0, 0, 0, 0); + + device_id = xcb_xkb_get_device_info_reply(xcb_connection(), device_id_cookie, 0); + if (!device_id) { qWarning("Qt: couldn't get core keyboard device info"); return; } + + core_device_id = device_id->deviceID; + free(device_id); } else { #endif m_key_symbols = xcb_key_symbols_alloc(xcb_connection()); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 9f1cf16..3beee7b 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -39,9 +39,6 @@ #include #include -#ifndef QT_NO_XKB -#include -#endif #include