Implement XCB key mapper in terms of QPlatformKeyMapper

Change-Id: I81af1200b7b1113062d66a76a185a6d15eab0ba9
Reviewed-by: Liang Qi <liang.qi@qt.io>
bb10
Tor Arne Vestbø 2023-09-21 13:19:57 +02:00
parent 1ffe7fbff0
commit d5c867ee29
9 changed files with 52 additions and 36 deletions

View File

@ -17,8 +17,6 @@
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcXkbcommon, "qt.xkbcommon")
static int keysymToQtKey_internal(xkb_keysym_t keysym, Qt::KeyboardModifiers modifiers,
xkb_state *state, xkb_keycode_t code,
bool superAsMeta, bool hyperAsMeta);
@ -596,10 +594,24 @@ static const Qt::KeyboardModifiers ModsTbl[] = {
Qt::NoModifier // Fall-back to raw Key_*, for non-latin1 kb layouts
};
/*
Compatibility until all sub modules have transitioned to new API below
*/
QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
bool superAsMeta, bool hyperAsMeta)
{
QList<int> result;
auto keyCombinations = possibleKeyCombinations(state, event, superAsMeta, hyperAsMeta);
for (auto keyCombination : keyCombinations)
result << keyCombination.toCombined();
return result;
}
QList<QKeyCombination> QXkbCommon::possibleKeyCombinations(xkb_state *state, const QKeyEvent *event,
bool superAsMeta, bool hyperAsMeta)
{
QList<QKeyCombination> result;
quint32 keycode = event->nativeScanCode();
if (!keycode)
return result;
@ -613,7 +625,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
ScopedXKBState scopedXkbQueryState(xkb_state_new(keymap));
xkb_state *queryState = scopedXkbQueryState.get();
if (!queryState) {
qCWarning(lcXkbcommon) << Q_FUNC_INFO << "failed to compile xkb keymap";
qCWarning(lcQpaKeyMapper) << Q_FUNC_INFO << "failed to compile xkb keymap";
return result;
}
// get kb state from the master state and update the temporary state
@ -639,7 +651,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
int baseQtKey = keysymToQtKey_internal(sym, modifiers, queryState, keycode, superAsMeta, hyperAsMeta);
if (baseQtKey)
result += (baseQtKey + int(modifiers));
result += QKeyCombination::fromCombined(baseQtKey + int(modifiers));
xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(keymap, "Shift");
xkb_mod_index_t altMod = xkb_keymap_mod_get_index(keymap, "Alt");
@ -685,8 +697,9 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
// catch only more specific shortcuts, i.e. Ctrl+Shift+= also generates Ctrl++ and +,
// but Ctrl++ is more specific than +, so we should skip the last one
bool ambiguous = false;
for (int shortcut : std::as_const(result)) {
if (int(shortcut & ~Qt::KeyboardModifierMask) == qtKey && (shortcut & mods) == mods) {
for (auto keyCombination : std::as_const(result)) {
if (keyCombination.key() == qtKey
&& (keyCombination.keyboardModifiers() & mods) == mods) {
ambiguous = true;
break;
}
@ -694,7 +707,7 @@ QList<int> QXkbCommon::possibleKeys(xkb_state *state, const QKeyEvent *event,
if (ambiguous)
continue;
result += (qtKey + int(mods));
result += QKeyCombination::fromCombined(qtKey + int(mods));
}
}
@ -726,7 +739,7 @@ void QXkbCommon::verifyHasLatinLayout(xkb_keymap *keymap)
// selected layouts is irrelevant. Properly functioning desktop environments
// handle this behind the scenes, even if no latin key based layout has been
// explicitly listed in the selected layouts.
qCDebug(lcXkbcommon, "no keyboard layouts with latin keys present");
qCDebug(lcQpaKeyMapper, "no keyboard layouts with latin keys present");
}
xkb_keysym_t QXkbCommon::lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode)
@ -800,7 +813,7 @@ void QXkbCommon::setXkbContext(QPlatformInputContext *inputContext, struct xkb_c
QMetaMethod method = inputContext->metaObject()->method(methodIndex);
Q_ASSERT(method.isValid());
if (!method.isValid())
qCWarning(lcXkbcommon) << normalizedSignature << "not found on" << inputContextClassName;
qCWarning(lcQpaKeyMapper) << normalizedSignature << "not found on" << inputContextClassName;
return method;
}();

View File

@ -23,12 +23,12 @@
#include <xkbcommon/xkbcommon.h>
#include <qpa/qplatformkeymapper.h>
#include <memory>
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcXkbcommon)
class QEvent;
class QKeyEvent;
class QPlatformInputContext;
@ -53,8 +53,10 @@ public:
static Qt::KeyboardModifiers modifiers(struct xkb_state *state, xkb_keysym_t keysym = XKB_KEY_VoidSymbol);
static QList<int> possibleKeys(xkb_state *state, const QKeyEvent *event,
bool superAsMeta = false, bool hyperAsMeta = false);
static QList<int> possibleKeys(xkb_state *state,
const QKeyEvent *event, bool superAsMeta = false, bool hyperAsMeta = false);
static QList<QKeyCombination> possibleKeyCombinations(xkb_state *state,
const QKeyEvent *event, bool superAsMeta = false, bool hyperAsMeta = false);
static void verifyHasLatinLayout(xkb_keymap *keymap);
static xkb_keysym_t lookupLatinKeysym(xkb_state *state, xkb_keycode_t keycode);

View File

@ -1141,13 +1141,6 @@ Qt::MouseButtons QXcbConnection::queryMouseButtons() const
return translateMouseButtons(stateMask);
}
Qt::KeyboardModifiers QXcbConnection::queryKeyboardModifiers() const
{
int stateMask = 0;
QXcbCursor::queryPointer(connection(), nullptr, nullptr, &stateMask);
return keyboard()->translateModifiers(stateMask);
}
QXcbGlIntegration *QXcbConnection::glIntegration() const
{
if (m_glIntegrationInitialized)

View File

@ -183,7 +183,6 @@ public:
QXcbSystemTrayTracker *systemTrayTracker() const;
Qt::MouseButtons queryMouseButtons() const;
Qt::KeyboardModifiers queryKeyboardModifiers() const;
bool isUserInputEvent(xcb_generic_event_t *event) const;

View File

@ -5,6 +5,7 @@
#include <xcb/xcb.h>
#include "qxcbconnection.h"
#include "qxcbclipboard.h"
#include "qxcbkeyboard.h"
#include "qxcbmime.h"
#include "qxcbwindow.h"
#include "qxcbscreen.h"
@ -768,7 +769,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
}
auto buttons = currentDrag() ? b : connection()->queryMouseButtons();
auto modifiers = currentDrag() ? mods : connection()->queryKeyboardModifiers();
auto modifiers = currentDrag() ? mods : connection()->keyboard()->queryKeyboardModifiers();
QPlatformDragQtResponse qt_response = QWindowSystemInterface::handleDrag(
w->window(), dropData, p, supported_actions, buttons, modifiers);
@ -1008,7 +1009,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
return;
auto buttons = currentDrag() ? b : connection()->queryMouseButtons();
auto modifiers = currentDrag() ? mods : connection()->queryKeyboardModifiers();
auto modifiers = currentDrag() ? mods : connection()->keyboard()->queryKeyboardModifiers();
QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(
currentWindow.data(), dropData, currentPosition, supported_drop_actions,

View File

@ -429,14 +429,9 @@ QPlatformServices *QXcbIntegration::services() const
return m_services.data();
}
Qt::KeyboardModifiers QXcbIntegration::queryKeyboardModifiers() const
QPlatformKeyMapper *QXcbIntegration::keyMapper() const
{
return m_connection->queryKeyboardModifiers();
}
QList<int> QXcbIntegration::possibleKeys(const QKeyEvent *e) const
{
return m_connection->keyboard()->possibleKeys(e);
return m_connection->keyboard();
}
QStringList QXcbIntegration::themeNames() const

View File

@ -74,8 +74,7 @@ public:
QPlatformServices *services() const override;
Qt::KeyboardModifiers queryKeyboardModifiers() const override;
QList<int> possibleKeys(const QKeyEvent *e) const override;
QPlatformKeyMapper *keyMapper() const override;
QStringList themeNames() const override;
QPlatformTheme *createPlatformTheme(const QString &name) const override;

View File

@ -3,6 +3,7 @@
#include "qxcbkeyboard.h"
#include "qxcbwindow.h"
#include "qxcbscreen.h"
#include "qxcbcursor.h"
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatforminputcontext.h>
@ -377,9 +378,18 @@ void QXcbKeyboard::updateKeymap()
QXkbCommon::verifyHasLatinLayout(m_xkbKeymap.get());
}
QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
QList<QKeyCombination> QXcbKeyboard::possibleKeyCombinations(const QKeyEvent *event) const
{
return QXkbCommon::possibleKeys(m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta);
return QXkbCommon::possibleKeyCombinations(
m_xkbState.get(), event, m_superAsMeta, m_hyperAsMeta);
}
Qt::KeyboardModifiers QXcbKeyboard::queryKeyboardModifiers() const
{
// FIXME: Should we base this on m_xkbState?
int stateMask = 0;
QXcbCursor::queryPointer(connection(), nullptr, nullptr, &stateMask);
return translateModifiers(stateMask);
}
void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)

View File

@ -14,11 +14,13 @@
#include <QtGui/private/qxkbcommon_p.h>
#include <xkbcommon/xkbcommon-x11.h>
#include <qpa/qplatformkeymapper.h>
#include <QEvent>
QT_BEGIN_NAMESPACE
class QXcbKeyboard : public QXcbObject
class QXcbKeyboard : public QXcbObject, public QPlatformKeyMapper
{
public:
QXcbKeyboard(QXcbConnection *connection);
@ -34,7 +36,9 @@ public:
Qt::KeyboardModifiers translateModifiers(int s) const;
void updateKeymap(xcb_mapping_notify_event_t *event);
void updateKeymap();
QList<int> possibleKeys(const QKeyEvent *event) const;
QList<QKeyCombination> possibleKeyCombinations(const QKeyEvent *event) const override;
Qt::KeyboardModifiers queryKeyboardModifiers() const override;
void updateXKBMods();
xkb_mod_mask_t xkbModMask(quint16 state);