我正在尝试在我的 cpp 程序中使用 X11 调整窗口大小并获取图像。不过,我似乎不知道如何使用新的宽度和高度更新窗口属性。
当调用 XResize 时,我的窗口确实会在系统上调整大小,但是当调用 XGetWindowAttributes 时,宽度和高度变量仍然是原始值。
我尝试重新映射我的窗口,调整大小后再次搜索我的窗口,将更新的宽度和高度属性保留在变量中,而不是获取窗口属性(这会在尝试调用子图像时使应用程序崩溃)。目前,如果我保留窗口的原始值,当调整大小的窗口大于原始值时,图像的溢出将被切断。
这是我正在测试的代码片段,我使用 alacritty 的实例作为我的测试窗口:
void SomeFunction(int w, int h){
std::cout << "Expected: " << w << " : " << h << std::endl;
XResizeWindow(m_display, *m_window, w, h);
XWindowAttributes attributes;
XGetWindowAttributes(m_display, *m_window, &attributes);
std::cout << "Actual: " << attributes.width << " : " << attributes.height << std::endl;
}
输出:
Expected 853 : 480
Actual: 800 : 600
X11 是一种客户端/服务器协议。
XResizeWindow() 向 X 服务器发送一条“非常感谢,我可以更改此窗口的大小吗”消息。
您当前的窗口管理器与您的 X 服务器有一个秘密安排,某种握手协议。任何时候任何 X 客户端想要更改其窗口的可见性或大小,X 服务器都会将请求转发给窗口管理器,窗口管理器对此主题拥有最终决定权。
因此,“非常感谢,我可以更改此窗口的大小吗”消息被转发到窗口管理器,因为它对此有深入的思考。同时,您询问窗口的当前属性,并发现窗口的大小与之前的大小完全相同。
当窗口管理器对请求进行橡皮图章时,只有然后您的窗口大小才会更改,并且您将收到一条
ConfigureNotify
消息(Configure
事件),告诉您窗口的新大小。
换句话说,您应该永远不要询问窗口的大小或位置。每当您的窗口大小或位置发生变化时,您都会收到通知,无论是响应您的请求还是用户手动拖动或调整窗口大小。