X11-XCB:窗口信息不是最新的吗?

问题描述

我正在使用XCB创建我的x11窗口,并且希望在代码中的某个位置移动它。

我做了一点测试以打印窗口位置(0,0),然后移动它,然后再次打印位置(200,100)。

此外,我总是x:10和y:10。

代码在这里

// g++ -o test test_xcb.cpp -lX11 -lxcb
#include <xcb/xcb.h>
#include <iostream>
using namespace std;

void print_window_xywh(xcb_connection_t *conn,xcb_drawable_t win)
{
    auto geo = xcb_get_geometry_reply(
       conn,xcb_get_geometry(conn,win),nullptr);

    cout << "Window( " << win << ") - x: " << geo->x 
         << " - y: " << geo->y 
         << " - w: " << geo->width
         << " - h: " << geo->height << endl;
}

int main(void) {
   xcb_connection_t *c;
   xcb_screen_t     *screen;
   xcb_window_t      win;

   /* Open the connection to the X server */
   c = xcb_connect (NULL,NULL);

   /* Get the first screen */
   screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;

   /* Ask for our window's Id */
   win = xcb_generate_id(c);

   /* Create the window */
   xcb_create_window (c,/* Connection          */
                     XCB_copY_FROM_PARENT,/* depth (same as root)*/
                     win,/* window Id           */
                     screen->root,/* parent window       */
                     10,10,/* x,y                */
                     150,150,/* width,height       */
                     10,/* border_width        */
                     XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class               */
                     screen->root_visual,/* visual              */
                     0,NULL);                      /* masks,not used yet */

   /* Map the window on the screen */
   xcb_map_window (c,win);

   /* Make sure commands are sent,so window is shown */
   xcb_flush (c);

   // Print the position and size of the window
   print_window_xywh(c,win);

   // Move the window
   const static uint32_t values[] = { 200,100 };
   xcb_configure_window(c,win,XCB_CONfig_WINDOW_X | XCB_CONfig_WINDOW_Y,values);
   
   // Print again,should be 200 for x and 100 for y
   print_window_xywh(c,win);

   return 0;
}

我错过了什么吗?谢谢。

解决方法

简短版本:您正在忽略与窗口管理器的交互。

长版:

首先,import {MiddlewareSequence} from '@loopback/rest'; export class MySequence extends MiddlewareSequence {} 的位置相对于父窗口。使用重新创建的窗口管理器,WM将在您的窗口周围添加一个框架窗口,以将窗口装饰绘制到(标题栏,关闭按钮等)。如果您希望窗口在屏幕上的位置,则应使用GetGeometry。对此请求的回复将使您将窗口xcb_translate_coordinates(c,win,screen->root,0)的位置转换为根窗口。

但是,在您的示例中,该方法仍然无效。这是因为窗口管理器是如何工作的。基本上,它禁止您的程序移动其窗口(0,0)。因此,当您尝试移动窗口时,X11服务器仅将此请求作为事件发送给窗口管理器。然后,窗口管理器需要一些时间来处理此请求。由于您将立即再次检查窗口位置,因此该请求尚未得到处理。