7.1.8 配置窗口
通常,我们在编写具有图形界面的应用程序时,在显示图形界面之前,一定会设置窗口的位置、尺寸或者边框宽度等。虽然读者可能反驳说,我们有时并没有设置这些啊?实际上,那是因为如GTK、QT等图形库已经帮我们做了。另外一种情况是在应用运行的某个中间时刻,应用也可能会改变窗口的这些信息。
X将这些信息统称为窗口配置,包括窗口的位置、宽度和高度,边框的宽度以及在栈中的位置。
在上述两种情况下,应用都将产生配置请求,X服务器也都会将它们重定向给窗口管理器。那么窗口管理器如何区分这两种情况呢?winman是这样处理的,当收到X服务器重定向来的配置请求时,winman调用函数wm_find_client_by_window遍历窗口栈,如果窗口栈中没有一个窗口对象与发送请求的窗口匹配,就说明这个窗口尚未被管理,否则说明这个窗口已经被管理了。
对于尚未纳入管理的应用的窗口,winman当然不能贸然管理,谁知道未来它是否需要管理呢。所以直接请求X服务器满足其需要。winman从事件XConfigureRequestEvent中提取信息,不加任何修改,完全照搬原来的配置请求,使用Xlib的函数XConfigureWindow直接代替应用向X服务器发出配置请求。
对于已被管理的窗口,winman调用具体窗口对象中处理配置的函数进行具体的配置。相关代码如下:
我们看到,当winman不了解“敌情”时,它直接调用Xlib的函数XConfigureWindow将“皮球”又踢给了X服务器。而对于已经在自己掌控之下的窗口,则调用具体窗口对象的配置处理函数进行配置。以标准窗口对象为例,函数指针configure指向normal_client_configure,其代码如下:
该函数的核心就是调用Xlib的XMoveResizeWindow系列函数,满足窗口的配置请求。但是有一点需要注意,因为应用的顶层窗口的配置改变了,所以所有的窗口装饰可能都需要进行调整。