Use X11 core protocol when xkb not available
To have a properly working key input in the xcb plugin in the case when xcb-xkb library is not available we can update the xkb_state struct with the keyboard state information available in the X11 core events. The current modifier state is reported to clients in a number of core protocol events and can be determined using the QueryPointer request. This is how it is done in Weston, Wayland's reference implementation. Note: In case the X server doesn't have a xkb support on it (which is very unlikely), then xkbcommon will only pick up the user's primary layout. The X server with the xkb support stuffs unused bits (13 and 14) of 'state' in the core events with the effective keyboard group, which we can use to determine layout changes. Change-Id: I9f1ef635109870e7412ef1157ca592f3c8f9271c Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>bb10
parent
260bfaf056
commit
43578e1901
|
|
@ -299,7 +299,10 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
|
|||
}
|
||||
|
||||
xcb_extension_t *extensions[] = {
|
||||
&xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id, &xcb_xkb_id,
|
||||
&xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
|
||||
#ifndef QT_NO_XKB
|
||||
&xcb_xkb_id,
|
||||
#endif
|
||||
#ifdef XCB_USE_RENDER
|
||||
&xcb_render_id,
|
||||
#endif
|
||||
|
|
@ -747,6 +750,7 @@ void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev)
|
|||
m_buttons &= ~translateMouseButton(event->detail);
|
||||
}
|
||||
|
||||
#ifndef QT_NO_XKB
|
||||
namespace {
|
||||
typedef union {
|
||||
/* All XKB events share these fields. */
|
||||
|
|
@ -761,6 +765,7 @@ namespace {
|
|||
xcb_xkb_state_notify_event_t state_notify;
|
||||
} _xkb_event;
|
||||
}
|
||||
#endif
|
||||
|
||||
void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||
{
|
||||
|
|
@ -786,12 +791,21 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||
case XCB_EXPOSE:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
|
||||
case XCB_BUTTON_PRESS:
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state);
|
||||
#endif
|
||||
handleButtonPress(event);
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
|
||||
case XCB_BUTTON_RELEASE:
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state);
|
||||
#endif
|
||||
handleButtonRelease(event);
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
|
||||
case XCB_MOTION_NOTIFY:
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state);
|
||||
#endif
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
|
||||
case XCB_CONFIGURE_NOTIFY:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
|
||||
|
|
@ -805,15 +819,29 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||
case XCB_ENTER_NOTIFY:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
|
||||
case XCB_LEAVE_NOTIFY:
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state);
|
||||
#endif
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
|
||||
case XCB_FOCUS_IN:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
|
||||
case XCB_FOCUS_OUT:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
|
||||
case XCB_KEY_PRESS:
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state);
|
||||
#endif
|
||||
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
|
||||
case XCB_KEY_RELEASE:
|
||||
#ifdef QT_NO_XKB
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
|
||||
#endif
|
||||
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
|
||||
#ifdef QT_NO_XKB
|
||||
case XCB_MAPPING_NOTIFY:
|
||||
m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
|
||||
break;
|
||||
#endif
|
||||
case XCB_SELECTION_REQUEST:
|
||||
{
|
||||
xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
|
||||
|
|
@ -876,6 +904,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||
}
|
||||
}
|
||||
handled = true;
|
||||
#ifndef QT_NO_XKB
|
||||
} else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295
|
||||
_xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event);
|
||||
if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
|
||||
|
|
@ -892,6 +921,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1574,6 +1604,7 @@ void QXcbConnection::initializeXShape()
|
|||
|
||||
void QXcbConnection::initializeXKB()
|
||||
{
|
||||
#ifndef QT_NO_XKB
|
||||
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id);
|
||||
if (!reply || !reply->present) {
|
||||
xkb_first_event = 0;
|
||||
|
|
@ -1629,6 +1660,7 @@ void QXcbConnection::initializeXKB()
|
|||
qWarning() << "Qt: failed to select notify events from xcb-xkb";
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(XCB_USE_EGL)
|
||||
|
|
|
|||
|
|
@ -673,8 +673,9 @@ void QXcbKeyboard::updateKeymap()
|
|||
xkb_state_unref(xkb_state);
|
||||
xkb_state = new_state;
|
||||
} else {
|
||||
// get initial state from the X server (and keep it up-to-date at all times)
|
||||
xkb_state = new_state;
|
||||
#ifndef QT_NO_XKB
|
||||
// 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;
|
||||
|
||||
|
|
@ -695,9 +696,13 @@ void QXcbKeyboard::updateKeymap()
|
|||
init_state->latchedGroup,
|
||||
init_state->lockedGroup);
|
||||
free(init_state);
|
||||
#else
|
||||
updateXKBMods();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QT_NO_XKB
|
||||
void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
|
||||
{
|
||||
if (!m_config)
|
||||
|
|
@ -715,11 +720,74 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
|
|||
state->lockedGroup);
|
||||
|
||||
if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
|
||||
qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
|
||||
{
|
||||
if (!m_config)
|
||||
return;
|
||||
|
||||
quint32 modsDepressed, modsLatched, modsLocked;
|
||||
modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
|
||||
modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
|
||||
|
||||
quint32 xkbMask = xkbModMask(state);
|
||||
xkb_state_component newState;
|
||||
newState = xkb_state_update_mask(xkb_state,
|
||||
modsDepressed & xkbMask,
|
||||
modsLatched & xkbMask,
|
||||
modsLocked & xkbMask,
|
||||
0,
|
||||
0,
|
||||
(state >> 13) & 3); // bits 13 and 14 report the state keyboard group
|
||||
|
||||
if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
|
||||
//qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
|
||||
}
|
||||
}
|
||||
|
||||
quint32 QXcbKeyboard::xkbModMask(quint16 state)
|
||||
{
|
||||
quint32 xkb_mask = 0;
|
||||
|
||||
if ((state & XCB_MOD_MASK_SHIFT) && xkb_mods.shift != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.shift);
|
||||
if ((state & XCB_MOD_MASK_LOCK) && xkb_mods.lock != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.lock);
|
||||
if ((state & XCB_MOD_MASK_CONTROL) && xkb_mods.control != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.control);
|
||||
if ((state & XCB_MOD_MASK_1) && xkb_mods.mod1 != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.mod1);
|
||||
if ((state & XCB_MOD_MASK_2) && xkb_mods.mod2 != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.mod2);
|
||||
if ((state & XCB_MOD_MASK_3) && xkb_mods.mod3 != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.mod3);
|
||||
if ((state & XCB_MOD_MASK_4) && xkb_mods.mod4 != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.mod4);
|
||||
if ((state & XCB_MOD_MASK_5) && xkb_mods.mod5 != XKB_MOD_INVALID)
|
||||
xkb_mask |= (1 << xkb_mods.mod5);
|
||||
|
||||
return xkb_mask;
|
||||
}
|
||||
|
||||
void QXcbKeyboard::updateXKBMods()
|
||||
{
|
||||
xkb_mods.shift = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT);
|
||||
xkb_mods.lock = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS);
|
||||
xkb_mods.control = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL);
|
||||
xkb_mods.mod1 = xkb_map_mod_get_index(xkb_keymap, "Mod1");
|
||||
xkb_mods.mod2 = xkb_map_mod_get_index(xkb_keymap, "Mod2");
|
||||
xkb_mods.mod3 = xkb_map_mod_get_index(xkb_keymap, "Mod3");
|
||||
xkb_mods.mod4 = xkb_map_mod_get_index(xkb_keymap, "Mod4");
|
||||
xkb_mods.mod5 = xkb_map_mod_get_index(xkb_keymap, "Mod5");
|
||||
}
|
||||
#endif
|
||||
|
||||
QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
|
||||
{
|
||||
// turn off the modifier bits which doesn't participate in shortcuts
|
||||
|
|
@ -846,11 +914,14 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
|
|||
, xkb_context(0)
|
||||
, xkb_keymap(0)
|
||||
, xkb_state(0)
|
||||
#ifndef QT_NO_XKB
|
||||
, core_device_id(0)
|
||||
#endif
|
||||
{
|
||||
updateKeymap();
|
||||
#ifndef QT_NO_XKB
|
||||
if (connection->hasXKB()) {
|
||||
|
||||
updateKeymap();
|
||||
updateVModMapping();
|
||||
updateVModToRModMapping();
|
||||
|
||||
|
|
@ -871,6 +942,10 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
|
|||
core_device_id = device_id->deviceID;
|
||||
free(device_id);
|
||||
}
|
||||
#else
|
||||
m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
|
||||
updateModifiers();
|
||||
#endif
|
||||
}
|
||||
|
||||
QXcbKeyboard::~QXcbKeyboard()
|
||||
|
|
@ -881,8 +956,12 @@ QXcbKeyboard::~QXcbKeyboard()
|
|||
xkb_keymap_unref(xkb_keymap);
|
||||
if (xkb_context)
|
||||
xkb_context_unref(xkb_context);
|
||||
#ifdef QT_NO_XKB
|
||||
xcb_key_symbols_free(m_key_symbols);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef QT_NO_XKB
|
||||
void QXcbKeyboard::updateVModMapping()
|
||||
{
|
||||
xcb_xkb_get_names_cookie_t names_cookie;
|
||||
|
|
@ -1004,14 +1083,67 @@ void QXcbKeyboard::updateVModToRModMapping()
|
|||
rmod_masks.altgr = modmap;
|
||||
}
|
||||
|
||||
#if 0
|
||||
qDebug() << "alt: " << rmod_masks.alt;
|
||||
qDebug() << "meta: " << rmod_masks.meta;
|
||||
qDebug() << "altgr: " << rmod_masks.altgr;
|
||||
#endif
|
||||
|
||||
free(map_reply);
|
||||
}
|
||||
#else
|
||||
void QXcbKeyboard::updateModifiers()
|
||||
{
|
||||
// The core protocol does not provide a convenient way to determine the mapping
|
||||
// of modifier bits. Clients must retrieve and search the modifier map to determine
|
||||
// the keycodes bound to each modifier, and then retrieve and search the keyboard
|
||||
// mapping to determine the keysyms bound to the keycodes. They must repeat this
|
||||
// process for all modifiers whenever any part of the modifier mapping is changed.
|
||||
memset(&rmod_masks, 0, sizeof(rmod_masks));
|
||||
|
||||
xcb_generic_error_t *error = 0;
|
||||
xcb_connection_t *conn = xcb_connection();
|
||||
xcb_get_modifier_mapping_cookie_t modMapCookie = xcb_get_modifier_mapping(conn);
|
||||
xcb_get_modifier_mapping_reply_t *modMapReply =
|
||||
xcb_get_modifier_mapping_reply(conn, modMapCookie, &error);
|
||||
if (error) {
|
||||
qWarning("Qt: failed to get modifier mapping");
|
||||
free(error);
|
||||
return;
|
||||
}
|
||||
|
||||
// for Alt and Meta L and R are the same
|
||||
static const xcb_keysym_t symbols[] = {
|
||||
XK_Alt_L, XK_Meta_L, XK_Mode_switch
|
||||
};
|
||||
static const size_t numSymbols = sizeof symbols / sizeof *symbols;
|
||||
|
||||
// Figure out the modifier mapping, ICCCM 6.6
|
||||
xcb_keycode_t* modKeyCodes[numSymbols];
|
||||
for (size_t i = 0; i < numSymbols; ++i)
|
||||
modKeyCodes[i] = xcb_key_symbols_get_keycode(m_key_symbols, symbols[i]);
|
||||
|
||||
xcb_keycode_t *modMap = xcb_get_modifier_mapping_keycodes(modMapReply);
|
||||
const int w = modMapReply->keycodes_per_modifier;
|
||||
for (size_t i = 0; i < numSymbols; ++i) {
|
||||
for (int bit = 0; bit < 8; ++bit) {
|
||||
uint mask = 1 << bit;
|
||||
for (int x = 0; x < w; ++x) {
|
||||
xcb_keycode_t keyCode = modMap[x + bit * w];
|
||||
xcb_keycode_t *itk = modKeyCodes[i];
|
||||
while (itk && *itk != XCB_NO_SYMBOL)
|
||||
if (*itk++ == keyCode) {
|
||||
uint sym = symbols[i];
|
||||
if ((sym == XK_Alt_L || sym == XK_Alt_R))
|
||||
rmod_masks.alt = mask;
|
||||
if ((sym == XK_Meta_L || sym == XK_Meta_R))
|
||||
rmod_masks.meta = mask;
|
||||
if (sym == XK_Mode_switch)
|
||||
rmod_masks.altgr = mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < numSymbols; ++i)
|
||||
free(modKeyCodes[i]);
|
||||
free(modMapReply);
|
||||
}
|
||||
#endif
|
||||
|
||||
class KeyChecker
|
||||
{
|
||||
|
|
@ -1076,8 +1208,17 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
|
|||
|
||||
if (!m_config)
|
||||
return;
|
||||
|
||||
// It is crucial the order of xkb_state_key_get_one_sym &
|
||||
// xkb_state_update_key operations is not reversed!
|
||||
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code);
|
||||
#ifdef QT_NO_XKB
|
||||
enum xkb_key_direction direction;
|
||||
if (type == QEvent::KeyPress)
|
||||
direction = XKB_KEY_DOWN;
|
||||
else
|
||||
direction = XKB_KEY_UP;
|
||||
xkb_state_update_key(xkb_state, code, direction);
|
||||
#endif
|
||||
|
||||
QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
|
||||
QMetaMethod method;
|
||||
|
|
@ -1194,13 +1335,20 @@ void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindowEventListener *eventListener,
|
|||
handleKeyEvent(window->window(), QEvent::KeyRelease, event->detail, event->state, event->time);
|
||||
}
|
||||
|
||||
void QXcbKeyboard::handleMappingNotifyEvent(const xcb_xkb_map_notify_event_t *)
|
||||
void QXcbKeyboard::handleMappingNotifyEvent(const void *event)
|
||||
{
|
||||
updateKeymap();
|
||||
#ifdef QT_NO_XKB
|
||||
void *ev = const_cast<void *>(event);
|
||||
xcb_refresh_keyboard_mapping(m_key_symbols, static_cast<xcb_mapping_notify_event_t *>(ev));
|
||||
updateModifiers();
|
||||
#else
|
||||
Q_UNUSED(event)
|
||||
if (connection()->hasXKB()) {
|
||||
updateKeymap();
|
||||
updateVModMapping();
|
||||
updateVModToRModMapping();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@
|
|||
|
||||
#include "qxcbobject.h"
|
||||
|
||||
#ifdef QT_NO_XKB
|
||||
#include <xcb/xcb_keysyms.h>
|
||||
#endif
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <QEvent>
|
||||
|
|
@ -62,14 +66,21 @@ public:
|
|||
void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event);
|
||||
void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event);
|
||||
|
||||
void handleMappingNotifyEvent(const xcb_xkb_map_notify_event_t *event);
|
||||
void handleMappingNotifyEvent(const void *event);
|
||||
|
||||
Qt::KeyboardModifiers translateModifiers(int s) const;
|
||||
QList<int> possibleKeys(const QKeyEvent *e) const;
|
||||
|
||||
void updateKeymap();
|
||||
void updateXKBState(xcb_xkb_state_notify_event_t *state);
|
||||
QList<int> possibleKeys(const QKeyEvent *e) const;
|
||||
|
||||
#ifdef QT_NO_XKB
|
||||
void updateXKBStateFromCore(quint16 state);
|
||||
void updateXKBMods();
|
||||
quint32 xkbModMask(quint16 state);
|
||||
#else
|
||||
int coreDeviceId() { return core_device_id; }
|
||||
void updateXKBState(xcb_xkb_state_notify_event_t *state);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
|
||||
|
|
@ -80,10 +91,16 @@ protected:
|
|||
int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const;
|
||||
|
||||
void readXKBConfig(struct xkb_rule_names *names);
|
||||
|
||||
#ifdef QT_NO_XKB
|
||||
void updateModifiers();
|
||||
#else
|
||||
void updateVModMapping();
|
||||
void updateVModToRModMapping();
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool m_config;
|
||||
xcb_keycode_t m_autorepeat_code;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
|
|
@ -96,12 +113,27 @@ private:
|
|||
uint meta;
|
||||
};
|
||||
|
||||
_mod_masks vmod_masks;
|
||||
_mod_masks rmod_masks;
|
||||
|
||||
int core_device_id;
|
||||
#ifdef QT_NO_XKB
|
||||
xcb_key_symbols_t *m_key_symbols;
|
||||
|
||||
bool m_config;
|
||||
struct _xkb_mods {
|
||||
xkb_mod_index_t shift;
|
||||
xkb_mod_index_t lock;
|
||||
xkb_mod_index_t control;
|
||||
xkb_mod_index_t mod1;
|
||||
xkb_mod_index_t mod2;
|
||||
xkb_mod_index_t mod3;
|
||||
xkb_mod_index_t mod4;
|
||||
xkb_mod_index_t mod5;
|
||||
};
|
||||
|
||||
_xkb_mods xkb_mods;
|
||||
#else
|
||||
_mod_masks vmod_masks;
|
||||
int core_device_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -111,7 +111,11 @@ contains(QT_CONFIG, xcb-qt) {
|
|||
} else {
|
||||
LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr
|
||||
!contains(DEFINES, QT_NO_SHAPE):LIBS += -lxcb-shape
|
||||
!contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb
|
||||
contains(DEFINES, QT_NO_XKB) {
|
||||
LIBS += -lxcb-keysyms
|
||||
} else {
|
||||
LIBS += -lxcb-xkb
|
||||
}
|
||||
}
|
||||
|
||||
# libxkbcommon
|
||||
|
|
|
|||
Loading…
Reference in New Issue