c++ 在XResizeWindow之后,X11不会更新WindowAttributes

nom7f22z  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(132)

我尝试在我的cpp程序中使用X11来调整窗口的大小并获取图像。尽管如此,我似乎不知道如何用新的宽度和高度来更新窗口属性。
当调用XResize时,我的窗口确实在我的系统上调整大小,但是当调用XGetWindowAttributes时,width和height变量仍然是原始值。
我尝试过重新Map我的窗口,重新调整后再次搜索我的窗口,将更新后的宽度和高度属性保留在变量中,而不是获取窗口属性(这会在尝试调用SubImage时崩溃应用程序)。目前,如果我保留原始值的窗口,当调整后的窗口大于原始值时,图像的溢出被切断。
下面是我正在测试的代码片段,我使用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

qnzebej0

qnzebej01#

X11是一个客户端/服务器协议。
XResizeWindow()向X服务器发送一个“请问,我可以改变这个窗口的大小吗?”消息。
您当前的窗口管理器与您的X服务器有一个秘密协议,一种握手协议。任何时候任何X客户端想要更改其窗口的可见性 * 或大小 *,X服务器将forward the request to the window manager,它对这个主题有最终决定权。
因此,“please,can I change this window's size”消息被转发到窗口管理器,让它沿着这些行进行深入的思考。同时,您询问窗口的当前属性,并发现窗口的大小与它一直以来的大小完全一样。
当窗口管理器橡皮图章的请求,只有 * 然后 * 你的窗口的大小改变,和you will get a ConfigureNotify message ( Configure event), that tells you your window's new size
换句话说,你应该 * 永远不要 * 询问你的窗口的大小或位置。你将 * 通知**任何时候你的窗口的大小或位置的变化,无论是响应你的请求还是用户手动拖动或拖动你的窗口。

nfs0ujit

nfs0ujit2#

这是我目前对这个问题的解决方案。
(NOTE:链接的存储库使用AGPL许可证)
我来的解决方案仍然涉及到再次找到窗口,类似于下面.虽然,重要的是使用ConfigureNotify,由@SamVarshavchick提到.你必须等待您的resize事件被接收.否则,当搜索窗口,结果可能是原始的窗口大小仍在处理.
推荐答案:
我已经解决了这个问题。。窗口的宽度和高度属性不会自动更新。关于为什么这是我不能提供的解释,但再次找到窗口确实会更新属性。
修复:

void SomeFunction(int w, int h){
    std::cout << "Expected: " << w << " : " << h << std::endl;
    XResizeWindow(m_display, *m_window, w, h);
    m_window = this->findWindowByName(m_rootWindow); // Find the window again
    XWindowAttributes attributes;
    XGetWindowAttributes(m_display, *m_window, &attributes);
    m_xImage = XGetImage(m_display, // Update the image we are working with
            *m_window,
            0,
            0,
            attributes.width,
            attributes.height,
            AllPlanes,
            ZPixmap);
    std::cout << "Actual: " << attributes.width << " : " << attributes.height << std::endl;
}

字符串
我不喜欢这个解决方案有两个原因。

  • 再花点时间去找Windows。
  • 调用XGetImage的代价很高,它在库中保存了一个图像副本,直到程序结束才释放。我的程序主要使用XGetSubImage来解决这个问题。

相关问题