Отправка события с помощью XSendEvent при получении указателя

Я разрабатываю плагин для оконного менеджера compiz. Я хочу нарисовать преобразованную текстуру окна и отправить событие в это окно. Когда трансформированное окно является средством визуализации, я беру указатель, чтобы взять контроль над всеми xevents, основная часть функции compiz, которая захватывает указатель, выглядит так:

 status = XGrabPointer (privateScreen.dpy, privateScreen.eventManager.getGrabWindow(), true,
                        POINTER_GRAB_MASK,
                        GrabModeAsync, GrabModeAsync,
                        privateScreen.rootWindow(), cursor,
                        CurrentTime);

Когда указатель захвачен, я пересчитываю координаты нажатия кнопки и использую XSendEvent для отправки событий в окно назначения. Он отлично работает для окна Google Chrome или для простого приложения xwindow, например: ссылка К сожалению, он не работает правильно для окна, которое выполняет рендеринг OpenGL - я протестировал SDL и GLFW. Такое окно получает события щелчка, но с другими параметрами (xbutton.x_root, xbutton.y_root, xbutton.x, xbutton.y), чем я указал в XSendEvent. Каждый раз, когда я отправляю событие, эти параметры содержат одинаковые значения, которые кажутся положением мыши до вызова xgrabpointer. Когда указатель не захвачен, события (из XSendEvent) принимаются правильно. Должно быть определенное отношение между xsendevent, xgrabpointer и окном, которое выполняет рендеринг OpenGL. Более того, реализация клиентов (окон) может отличаться, потому что мой код не работает только для этих конкретных окон или, может, я что-то не так делаю?

Edit1

Давайте рассмотрим следующий пример: у меня есть полноэкранное окно, затем я могу использовать плагин для рисования текстуры трансформированного окна (например, преобразование масштаба (0,5, 0,5, 1,0)), но X11 по-прежнему видит полноэкранное окно, поэтому, когда я нажимаю на область за пределами трансформированного события текстуры перейти к окну. Когда я получаю указатель в плагине, я являюсь единственным получателем всех событий, тогда я могу пересчитать координаты на основе трансформации моего окна и отправить их в окно.

Edit2 Когда я использую Freeglut, все события правильно отправляются в окно назначения, когда указатель захвачен. Должны быть некоторые различия между реализациями библиотеки.

2 ответа

OpenGL не связан с событиями ввода, он просто рисует вещи, даже не зная, что такое события X11 или указатели.

Это должно быть то, что и SDL, и GLFW делают в своих настройках окна.

Однако мне интересно, почему вы вообще берете указатель? Расширение X Composite, являющееся основой для построения Compiz и других композитных WM, уже имеет специальный API для преобразования ввода указателя, см. http://www.x.org/archive/X11R7.5/doc/compositeproto/compositeproto.txt RedirectCoordinate а также TransformCoordinate , Вы должны использовать эти функции вместо того, чтобы возиться с захватом указателя. Захват указателя - действительно очень плохая идея.

Хорошо, кажется, что копия составного расширения X, которое я связал (и у меня есть на моем компьютере), является более ранним проектом, в котором все еще есть RedirectCoordinate. Есть более новая версия (которая, к сожалению, содержит ту же дату в заголовке - WTF?), Где перенаправление координат было удалено.

SDL обновляет положение мыши при обработке события MouseMotion. Он не использует координаты, которые хранятся в событии ButtonPress. Когда оконный менеджер захватывает указатель и отправляет событие ButtonPress в окно SDL, положение мыши внутри приемника не обновляется. Вот пример решения (следующий код должен быть добавлен в раздел после метки ButtonPress в SDL_x11events.c:

if(xevent.xany.send_event)
{
     SDL_Mouse *mouse = SDL_GetMouse();
     mouse->x = xevent.xbutton.x;
     mouse->y = xevent.xbutton.y;
}
Другие вопросы по тегам