在X11中,我如何在创建窗口之前设置窗口标题?

4

背景:

我在xmonad下使用glfw。Glfw显然是在创建窗口之后设置窗口标题,因此不能使xmonad正确处理它。我想修改glfw源代码,以便在创建窗口之前设置窗口标题。

问题:

所以我下载了glfw-2.6,并查看 lib / x11 / x11_window.c; 导致麻烦的行是:

// Create a window
_glfwWin.Win = XCreateWindow(
    _glfwLibrary.Dpy,
    RootWindow( _glfwLibrary.Dpy, _glfwWin.VI->screen ),
    0, 0,                            // Upper left corner
    _glfwWin.Width, _glfwWin.Height, // Width, height
    0,                               // Borderwidth
    _glfwWin.VI->depth,              // Depth
    InputOutput,
    _glfwWin.VI->visual,
    CWBorderPixel | CWColormap | CWEventMask,
    &wa
);

稍后跟随:

_glfwPlatformSetWindowTitle( "GLFW Window" );

在哪里

void _glfwPlatformSetWindowTitle( const char *title )
{
    // Set window & icon title
    XStoreName( _glfwLibrary.Dpy, _glfwWin.Win, title );
    XSetIconName( _glfwLibrary.Dpy, _glfwWin.Win, title );
}

现在,如果我在CreateWindow调用之前尝试移动glfwPlatformSetWindowTitle调用,我会得到一个segfault -- 因为_glfwWin.win未定义,所以我应该这样做。
我不知道如何解决这个问题,因为要设置窗口标题,我需要_glfwWin.Win被初始化,但是为了初始化它,我需要创建窗口。
因此,我想问:在X11中,在创建窗口之前设置窗口标题的正确方法是什么?
谢谢!
1个回答

3
这在X11中是不可能的,但对于程序工作来说也不是必要的。一定有某个bug导致你看到的症状。窗口标题只是窗口上的一个属性,而属性不能存在于没有窗口的情况下。
你说“不允许xmonad正确处理它”,这意味着它无法应对名称的更改;窗口管理器绝对必须在任何时候处理设置标题,包括在创建窗口后长时间更改标题。
规范所说的是(http://www.x.org/docs/ICCCM/icccm.pdf):“当窗口从Withdrawn状态转换时,窗口管理器将检查这些属性的内容,并在窗口处于Iconic或Normal状态时监视一些属性的变化。”
“从Withdrawn状态转换”是glfw调用XMapWindow()的时刻。此时,窗口将保持未映射状态,但WM将收到MapRequest。然后,WM会读取属性等,然后映射窗口。我见过的所有窗口管理器都处理后来的属性更改,因为更改窗口标题非常正常。例如,网页浏览器每个url都有页面标题。
如果xmonad不能处理更改,也许它至少会等待映射,因此您只需要在XMapWindow()之前设置标题。实际上,所有设置都应该在MapWindow之前完成,但根据规范,只有一些属性是必须在其之前设置的。通常必须在其之前设置的属性不能在未映射时更改。
顺便说一下,_glfwPlatformSetWindowTitle仅适用于Latin-1,现代的做法是使用XChangeProperty()设置_NET_WM_NAME和_NET_WM_ICON_NAME(将旧的Latin-1 WM_NAME设置为后备方案也可以)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接