XI2. Как игнорировать события клавиш-модификаторов? - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь исправить xneur переключатель клавиатуры. Его автор попытался добавить поддержку XI2, но сломал ввод в приложениях, которые используют только XI2 (например, Google Chrome).

И я застрял с фильтрацией модификаторов. Существует следующий код :

// Grab all keys...
if (has_x_input_extension) {
    XIEventMask mask;
    mask.deviceid = XIAllDevices;
    mask.mask_len = XIMaskLen(XI_KeyPress)+
                    XIMaskLen(XI_KeyRelease);
    mask.mask = (void *)calloc(mask.mask_len, sizeof(char));
    XISetMask(mask.mask, XI_KeyPress);
    XISetMask(mask.mask, XI_KeyRelease);
    XISelectEvents(main_window->display, DefaultRootWindow(main_window->display), &mask, 1);
    free(mask.mask);
}
else {
    XGrabKey(main_window->display, AnyKey, AnyModifier, window, FALSE, GrabModeAsync, GrabModeAsync);
    // ...without ModKeys.
    grab_modifier_keys(window, FALSE);
}

grab_modifier_keys, позволяющий разблокировать ключевые модификаторы. И я не знаю, как сделать то же самое с XI2 (ветвь if).


Я думаю, что можно игнорировать эти события в цикле обработки событий . Примерно так:

int is_modifier (XEvent *event)
{ 
    /* ??? */
}

while (1) {
    XEvent event;
    XNextEvent(display, &event);
    if (is_modifier(event)) {
        continue;
    } 
}

Но я не знаю, как реализовать функцию is_modifier.

Буду признателен за любую помощь

1 Ответ

0 голосов
/ 08 октября 2019

Возможно, не идеальное решение, но вот реализация is_modifier Я придумал:

Bool is_modifier(KeySym key_sym)
{
    XModifierKeymap *modmap = XGetModifierMapping(main_window->display);
    if (modmap == NULL) {
        return False;
    }

    KeyCode key_code = XKeysymToKeycode(main_window->display, key_sym);

    int size = modmap->max_keypermod * 8;
    for (int i = 0; i < size; ++i) {
        if (key_code == modmap->modifiermap[i]) {
            return True;
        }
    }

    XFreeModifiermap(modmap);

    return False;
}
...