Не удается отсоединить клавиатуру после XGrabKeyboard - PullRequest
0 голосов
/ 12 апреля 2019

Я разрабатываю приложение, которое должно заморозить весь ввод, как клавиатуры, так и мыши, на определенный период времени.Я пытался использовать XGrabKeyboard, но я не могу восстановить его эффект, используя XUngrabKeyboard, он ничего не делает.

Вот минимальный пример, который вы можете легко скомпилировать:

#include <iostream>
#include <thread>
#include <chrono>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/cursorfont.h>


int main(int argc, char *argv[])
{
    Display * dpy = nullptr;

    dpy = XOpenDisplay(0);

    if(!dpy)
    {
        std::cerr << "Error" << std::endl;
        return 1;
    }

    std::cerr << "Grabbing..." << std::endl;

    XGrabKeyboard(dpy, DefaultRootWindow(dpy), false, GrabModeAsync, GrabModeAsync, CurrentTime);

    std::cerr << "Waiting 2 secs, you shouldn't be able to type anything" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));


    std::cerr << "Ungrabbing..." << std::endl;
    XUngrabKeyboard(dpy, CurrentTime);

    std::cerr << "Try to type now" << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}

Вы можетевижу, что вы не можете больше ничего писать.Я пытался нажать на терминал, в случае, если фокус потерян или что-нибудь, но безрезультатно.Как только программа завершает работу, клавиатура освобождается.

Не уверен, имеет ли она какое-то отношение к параметрам в вызове XGrabKeyboard, я попытался изменить их (синхронизация с асинхронным вызовом и т. Д.).Но нет никакой разницы.

1 Ответ

1 голос
/ 12 апреля 2019

Добавление XSync(dpy, true); (*) после XUngrabKeyboard заставляет код вести себя так, как вы ожидали.Так что, возможно, вам нужно обработать все события, которые вы захватили до возобновления очереди событий?

(*): на самом деле не делайте этого, это просто для того, чтобы продемонстрировать, что проблема связана с событиями в очереди

Также работает:

XUngrabKeyboard(dpy, CurrentTime);
XEvent foo;
while (XPending(dpy)) XNextEvent(dpy, &foo);

Обновление - также работает:

XFlush(dpy);

Итак ... проблема в том, что на самом деле ungrab не был отправлен?

...