0

我为compiz窗口管理器开发了一个插件。我想绘制一个转换后的窗口纹理并向该窗口发送一个事件。当转换的窗口是渲染器时,我抓取指针以控制所有 xevents,抓取指针的 compiz 函数的主要部分如下所示:

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

当一个指针被抓住时,我重新计算按钮按下坐标,并使用XSendEvent将事件发送到目标窗口。它适用于 google chrome 窗口或像这样的简单 xwindow 应用程序:link不幸的是,对于执行 OpenGL 渲染的窗口,它不能正常工作——我已经测试了 SDL 和 GLFW。这样的窗口接收点击事件,但参数(xbutton.x_root、xbutton.y_root、xbutton.x、xbutton.y)与我在 XSendEvent 中指定的不同。每次我发送事件时,这些参数都包含相同的值,这些值似乎是调用 xgrabpointer 之前的鼠标位置。当指针未被抓取时,事件(来自 XSendEvent)被正确接收。xsendevent、xgrabpointer 和执行 OpenGL 渲染的窗口之间必须存在某种特定关系。此外,客户端(Windows)实现可能会有所不同,因为我的代码仅适用于该特定窗口,或者我做错了什么?

编辑1

让我们考虑下面的例子:我有一个全屏窗口,然后我可以使用一个插件来绘制变换的窗口纹理(例如缩放变换 (0.5, 0.5, 1.0)),但是 X11 仍然看到一个全屏窗口,所以当我点击转换纹理事件之外的区域转到窗口。当我在插件中抓取指针时,我是所有事件的唯一接收者,然后我可以根据我的窗口变换重新计算坐标并将它们发送到窗口。

Edit2 当我使用 Freeglut 时,所有事件都会在指针被抓取时正确发送到目标窗口。库实现之间必须存在一些差异。

4

2 回答 2

1

OpenGL 不关心输入事件,它只是绘制东西,甚至不知道 X11 或指针事件是什么。

这必须是 SDL 和 GLFW 在其窗口设置中所做的事情。

但是我想知道你为什么要抓住指针?X Composite 扩展是构建 Compiz 和其他合成 WM 的基础,它已经具有用于指针输入转换的专用 API,请参阅http://www.x.org/archive/X11R7.5/doc/compositeproto/compositeproto .txt RedirectCoordinateTransformCoordinate. 您应该使用这些功能,而不是乱抓指针。抓住指针是一个非常非常糟糕的主意。

好的,我链接的 X 复合扩展的副本(我的计算机上有)似乎是早期的草稿,其中仍然包含 RedirectCoordinate。有一个较新的版本(不幸的是,它的头部带有相同的日期 - WTF?)其中坐标重定向已被删除。

于 2014-12-19T09:04:05.167 回答
0

SDL 在处理 MouseMotion 事件时更新鼠标位置。它不使用存储在 ButtonPress 事件中的坐标。当窗口管理器获取指针并将 ButtonPress 事件发送到 SDL 窗口时,接收器内的鼠标位置不会更新。这是示例解决方案(以下代码应添加到 SDL_x11events.c 中 ButtonPress 标签后的部分:

if(xevent.xany.send_event)
{
     SDL_Mouse *mouse = SDL_GetMouse();
     mouse->x = xevent.xbutton.x;
     mouse->y = xevent.xbutton.y;
}
于 2015-01-13T07:18:36.043 回答