如何正确等待X11窗口被映射和可见?准确地说,我想等到可以安全地调用XSetInputFocus()而不会遇到X服务器反弹以下错误的任何风险:
// X Error of failed request: BadMatch (invalid parameter attributes)
// Major opcode of failed request: 42 (X_SetInputFocus)
目前这个错误经常发生,特别是在慢的X服务器上或者在使用libXrandr更改监视器分辨率后立即尝试打开新窗口时。
我已经有一个解决方案,但它相当hacky,因为它轮询窗口属性,所以我想知道是否有更清晰的版本。
这是我目前的方法:
static Bool predicate(Display *display, XEvent *ev, XPointer arg)
{
return(ev->type == MapNotify);
}
static void waitmapnotify(struct osdisplayinfo *osd)
{
XEvent ev;
XWindowAttributes xwa;
XPeekIfEvent(osd->display, &ev, predicate, NULL);
do {
XGetWindowAttributes(osd->display, osd->window, &xwa);
usleep(1);
} while(xwa.map_state != IsViewable);
}
这段代码可以正常工作,但是它有些hacky,所以我在这里提出讨论 - 以防有更干净的方法来完成这个任务。