据我所知,只要窗口进入焦点状态,就会触发X11 FocusIn事件。它就是将键盘输入发送到的窗口。触发此事件时遇到问题。在创建窗口时,我已经确保给它提供了FocusChangeMask。我已经在我的事件处理程序中创建了一个断点,该断点是FocusIn事件应该发生的位置,但它并没有停止。
我有两个独立的窗口,一个透明的和一个不透明的。目前我有它,所以透明窗口总是在非透明窗口的顶部。每当我切换焦点,然后切换回透明窗口时,非透明窗口就在正下方。这会导致其他窗口卡在透明窗口和非透明窗口之间。
我注意到,每当我关注触发FocusIn事件的非透明窗口时。我无法让透明窗口触发事件。这与32位颜色的窗口有关系吗?
我遗漏了什么?
while(!renderer->stop)
{
XNextEvent(renderer->x_display, &event);
switch(event.type)
{
case Expose:
if (event.xexpose.window == gstreamer_window)
{
XRaiseWindow(renderer->x_display, renderer->opengl_window);
}
break;
case FocusIn:
if (event.xfocus.window == renderer->opengl_window)
{
XRaiseWindow(renderer->x_display, gstreamer_window);
}
break;
case ConfigureNotify:
if (event.xconfigure.window == renderer->opengl_window)
{
XMoveWindow(renderer->x_display, gstreamer_window,
event.xconfigure.x, event.xconfigure.y - top_border_offset);
}
break;
}
}
下面是我创建窗口的方法。
XSetWindowAttributes swa;
swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask | FocusChangeMask;
swa.colormap = XCreateColormap(x_display, XDefaultRootWindow(x_display), visual, AllocNone);
swa.background_pixel = 0;
swa.border_pixel = 0;
/* Create a window */
opengl_window = XCreateWindow (
x_display, parent,
0, 0, m_plane_width, m_plane_height, 0,
depth, InputOutput,
visual, CWEventMask | CWBackPixel | CWColormap | CWBorderPixel,
&swa );
发布于 2015-09-12 02:54:38
看起来好像我把FocusChangeMask放错了地方。通过添加行XSelectInput(x_display, opengl_window, FocusChangeMask)
,它现在触发了FocusIn事件。它触发了另一个显示器,因为它有遮罩,但这个没有。
发布于 2015-09-01 06:16:55
从您的问题中不清楚您的问题中引用的窗口是顶级应用程序窗口,还是作为顶级应用程序窗口的子窗口的辅助辅助窗口。
但在所有情况下,正确的输入焦点处理都要求您准确地通知窗口管理器您的应用程序期望如何处理输入焦点。
有关详细信息,请参阅section 4.1.7 of the ICCCM specification。不幸的是,仅仅编写一个处理FocusIn
消息的事件循环并期望它们从天而降是不够的。首先,您需要确切地告诉窗口管理器您将如何处理输入焦点切换,然后响应窗口管理器的消息,如ICCCM规范中所述;可能是显式地为您自己的应用程序窗口发送SetInputFocus请求。
https://stackoverflow.com/questions/32319257
复制相似问题