X11 События MotionNotify не отображаются в отдельной общей библиотеке? - PullRequest
1 голос
/ 03 февраля 2012

У меня есть две общие библиотеки: одна для настройки окон и рендеринга в них с помощью opengl, а другая отдельная библиотека ввода, которая собирает данные ввода от мыши и клавиатуры для окон, созданных в библиотеке рендеринга.

Теперь я могу правильно получать события в библиотеке рендеринга, такие как мышь, клавиатура и другие события. Я также могу получить ключевые события во входной библиотеке, но события мыши не отправляются. У меня настроен выход отладки, который показывает возвращаемое значение XPending() т.е. количество событий в очереди, а в библиотеке рендеринга это показывает кучу событий. Перемещение мыши или щелчок по ней приводит к тому, что в очередь попадает больше событий. Во входной библиотеке у меня также есть этот отладочный вывод. Клавиатура показывает только 1 событие, когда клавиша нажата / отпущена, и ноль в противном случае. Однако мышь всегда показывает ноль событий.

Чтобы получить мой дескриптор окна X, у меня в классе окна есть функция, которая возвращает 64-битное целое число, достаточно большое, чтобы содержать дескриптор окна в X11 и Windows (поскольку мои библиотеки кроссплатформенные). В библиотеке ввода я приведу это обратно к дескриптору окна X. Чтобы получить мой дисплей X, я вызываю XOpenDisplay(0) в конструкторе мыши / клавиатуры.

Так почему я получаю события мыши в моей библиотеке рендеринга, а не в моей библиотеке ввода?

EDIT: Здесь - это исходный код, который показывает проблему (~ 200 строк кода)

1 Ответ

0 голосов
/ 17 февраля 2012

Наличие нескольких открытых дисплеев усложняет задачу.В этом случае у вас есть несколько отдельных сокетов и потоков команд / событий на X-сервере, и вы видите на X-сервере несколько разных приложений (разных клиентов).

Порядок обработки запросов и событий не определенчерез два разных соединения.Например, если пользователь нажимает клавишу, а затем перемещает мышь, вы получите их в том же порядке на том же дисплее, но в любом порядке на двух разных дисплеях.

Один приемустановка, подобная этой, заключается в том, что любые ресурсы X (окна, GC и т. д.), которые вы создаете на одном дисплее, НЕ обязательно будут видны для другого соединения дисплея, пока вы не выполните XSync ().Это связано с тем, что идентификаторы создаются на стороне клиента, а затем сбрасываются на X-сервер.XSync () сбрасывает запрос на создание ресурса и гарантирует, что X-сервер обработал запрос.(Точнее: любой запрос туда-обратно - тот, который должен ждать ответа - будет делать это; XSync внутренне просто выполняет XGetInputFocus (), который является произвольно выбранным запросом туда-обратно. Так что, если вы знаете, какие запросы являются обходамипосле этого вам не нужно синхронизироваться.)

Хитрость указателя и клавиатуры также сложны.Захват привязывает указатель или клавиатуру к определенному соединению.Таким образом, всякий раз, когда вы захватываете, ваш другой Дисплей не будет получать события, охватываемые захватом, пока вы не снимите захват.

XGrabServer () еще сложнее;этот запрос просит X-сервер прекратить обработку запросов и отправку событий для всех дисплеев, кроме экрана с захватом сервера.Поэтому, если один из ваших дисплеев захватывает сервер, любая попытка использовать другой, вероятно, заблокирует вашу программу.

Наконец, ваши входные маски (здесь передаются в XCreateWindow, но см. XSelectInput) для каждого display-подключение.Я думаю, что это может быть вашей реальной проблемой;некоторые из ваших дисплеев не запрашивали необходимые события в окне.Но я не проверял это.

Я бы предложил один раз вызвать XOpenDisplay (), а затем передать один экран другому вашему другому коду.Это сделает вещи намного менее сложными и, возможно, даже решит проблему.

...