[tabbox] Port keysym and modifier mapping to XCB

REVIEW: 122454
icc-effect-5.14.5
Martin Gräßlin 2015-02-06 15:17:56 +01:00
parent dfa89cc050
commit 2a29324294
2 changed files with 77 additions and 9 deletions

View File

@ -55,6 +55,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// X11
#include <X11/keysym.h>
#include <X11/keysymdef.h>
// xcb
#include <xcb/xcb_keysyms.h>
// specify externals before namespace
@ -900,19 +902,40 @@ void TabBox::grabbedKeyEvent(QKeyEvent* event)
m_tabBox->grabbedKeyEvent(event);
}
struct KeySymbolsDeleter
{
static inline void cleanup(xcb_key_symbols_t *symbols)
{
xcb_key_symbols_free(symbols);
}
};
/*!
Handles alt-tab / control-tab
*/
static bool areKeySymXsDepressed(bool bAll, const uint keySyms[], int nKeySyms) {
char keymap[32];
qDebug() << "areKeySymXsDepressed: " << (bAll ? "all of " : "any of ") << nKeySyms;
XQueryKeymap(display(), keymap);
Xcb::QueryKeymap keys;
QScopedPointer<xcb_key_symbols_t, KeySymbolsDeleter> symbols(xcb_key_symbols_alloc(connection()));
if (symbols.isNull() || !keys) {
return false;
}
const auto keymap = keys->keys;
for (int iKeySym = 0; iKeySym < nKeySyms; iKeySym++) {
uint keySymX = keySyms[ iKeySym ];
uchar keyCodeX = XKeysymToKeycode(display(), keySymX);
xcb_keycode_t *keyCodes = xcb_key_symbols_get_keycode(symbols.data(), keySymX);
if (!keyCodes) {
continue;
}
xcb_keycode_t keyCodeX = keyCodes[0];
free(keyCodes);
if (keyCodeX == XCB_NO_SYMBOL) {
continue;
}
int i = keyCodeX / 8;
char mask = 1 << (keyCodeX - (i * 8));
@ -1440,12 +1463,20 @@ void TabBox::keyRelease(const xcb_key_release_event_t *ev)
if (mod_index == -1)
release = true;
else {
XModifierKeymap* xmk = XGetModifierMapping(display());
for (int i = 0; i < xmk->max_keypermod; i++)
if (xmk->modifiermap[xmk->max_keypermod * mod_index + i]
== ev->detail)
release = true;
XFreeModifiermap(xmk);
Xcb::ModifierMapping xmk;
if (xmk) {
xcb_keycode_t *keycodes = xmk.keycodes();
const int maxIndex = xmk.size();
for (int i = 0; i < xmk->keycodes_per_modifier; ++i) {
const int index = xmk->keycodes_per_modifier * mod_index + i;
if (index >= maxIndex) {
continue;
}
if (keycodes[index] == ev->detail) {
release = true;
}
}
}
}
if (!release)
return;

View File

@ -605,6 +605,43 @@ public:
}
};
struct QueryKeymapData : public WrapperData< xcb_query_keymap_reply_t, xcb_query_keymap_cookie_t >
{
static constexpr request_func requestFunc = &xcb_query_keymap_unchecked;
static constexpr reply_func replyFunc = &xcb_query_keymap_reply;
};
class QueryKeymap : public Wrapper<QueryKeymapData>
{
public:
QueryKeymap() : Wrapper<QueryKeymapData>() {}
};
struct ModifierMappingData : public WrapperData< xcb_get_modifier_mapping_reply_t, xcb_get_modifier_mapping_cookie_t >
{
static constexpr request_func requestFunc = &xcb_get_modifier_mapping_unchecked;
static constexpr reply_func replyFunc = &xcb_get_modifier_mapping_reply;
};
class ModifierMapping : public Wrapper<ModifierMappingData>
{
public:
ModifierMapping() : Wrapper<ModifierMappingData>() {}
inline xcb_keycode_t *keycodes() {
if (isNull()) {
return nullptr;
}
return xcb_get_modifier_mapping_keycodes(data());
}
inline int size() {
if (isNull()) {
return 0;
}
return xcb_get_modifier_mapping_keycodes_length(data());
}
};
XCB_WRAPPER_DATA(PropertyData, xcb_get_property, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t)
class Property : public Wrapper<PropertyData, uint8_t, xcb_window_t, xcb_atom_t, xcb_atom_t, uint32_t, uint32_t>
{