所以在那种情况下,我认为是 Gtk 应用了窗户装饰。这是如何运作的?
正确的。GTK 应用程序告诉窗口管理器不要通过将边框宽度设置为 0 来装饰它们。现在我的建议是只实现:如果窗口将边框宽度设置为 0,则忽略它的装饰。一开始我不会打扰其他任何事情。事实上,你现在甚至可以忽略这个提示。
我读到 EWMH 窗口属性 […]
现在不要打扰 EWMH。只需装饰所有未将边框设置为 0 的托管窗口。此外,我看不出为什么不应该装饰其他窗口类型(如对话框)的充分理由;我不认为窗口管理器真的使用这个属性来确定这一点,但我只能肯定地说一对夫妇。
这是您正常绘制窗户装饰的方式吗?或者我可以为此使用 Gtk(或其他东西)吗?
虽然您没有明确要求这样做,但此引文中的最后一句话告诉我您可能不完全了解装饰的工作原理。最常见的方法,我强烈建议您这样做,称为reparenting。
Reparenting 意味着当您管理一个窗口时,您创建一个称为框架窗口的新窗口(当然您不应该像普通客户端窗口那样管理它) ,然后将客户端窗口重新设置为您的框架窗口。所以实际的顶层窗口是窗口管理器拥有的框架窗口;客户端窗口(用户与之交互的窗口)是它的直接子窗口。
现在您只需使框架窗口略大于客户端窗口并将客户端窗口正确放置在其中。当然,您需要跟踪客户端窗口的大小调整并对其采取行动。
那么我们为什么要创建这个框架窗口呢?简单的!因为您可以创建一个用于它并在其上绘制标题栏的像素图。这比直接在子窗口上绘图要好,因为您不会弄乱您实际上并不拥有的窗口。
绘图可以通过“原始”和简单的调用来完成,xcb_poly_fill_rectangle
或者您可以使用更复杂的方法,例如,使用像 cairo 这样的库(我会推荐)。例如,i3 窗口管理器使用一个简单的抽象,通过编译标志 (libi3/draw_util.c) 支持两者。
这种重新设置方法是工具xwininfo
可以选择xprop
的原因-frame
。默认情况下,这些工具实际上忽略了框架窗口并下降到客户端窗口,几乎隐藏了存在框架窗口的事实。只需在同一个窗口上尝试xprop
,xprop -frame
您就会发现框架窗口附加的信息要少得多。
一旦你重新设计和绘图,你就可以更多地考虑你不需要/不想装饰窗户的情况。鉴于这里有很多事情要跟踪,我认为一开始实施这个会让你忙一段时间。我强烈建议研究其他简单的窗口管理器的代码。