无法让XCreateSimpleWindow在正确的位置打开窗口

时间:2012-06-17 07:33:28

标签: x11

以下代码打开一个正确大小的窗口,w,h,但不在正确的位置x,y。

#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
using namespace std;

int main(int argc, char* argv[]){
  Display *display; // A connection to X server
  int screen_number;
  Window canvas_window;
  unsigned long white_pixel;
  unsigned long black_pixel;

  display = XOpenDisplay(NULL);    // Connect X server by opening a display

  if(!display){
    cerr<<"Unable to connect X server\n";
    return 1;
  }

  screen_number = DefaultScreen(display);
  white_pixel = WhitePixel(display, screen_number);
  black_pixel = BlackPixel(display, screen_number);


  int x=0, y=100, w=300, h=400;

  canvas_window = XCreateSimpleWindow(display,
                                      RootWindow(display, screen_number),
                                      x,y,  // top left corner
                                      w,h,  // width and height
                                      2,    // border width
                                      black_pixel,
                                      white_pixel);

  XMapWindow(display, canvas_window);    // Map canvas window to display
  XSync(display, False);

  cin >> x;   // just so that the program does not end
}

我用g ++ xwindowtest.cpp -lX11编译了这个,其中g ++是版本4.6.2并在Debian GNU / Linux下运行。

3 个答案:

答案 0 :(得分:7)

上述解决方案有点正确,但并不完整。

在桌面上创建一个新的顶级窗口,并在应用程序的顶级窗口中创建一个新的(子)窗口,使用相同的XCreateSimpleWindow()调用,但实际行为可能不同。

在您的应用程序中创建一个新的子窗口时,您负责,并且您将为新窗口提供原点坐标(相对于其父窗口的原点)和大小。换句话说,窗口将移动到您想要的位置。

然而,当在桌面上创建一个新的顶级窗口时,你必须处理讨厌的窗口管理器,例如Motif,KDE,Gnome等。当你创建一个顶层窗口来添加边框时,这会介入(“装饰“”,标题,可能是图标等等。默认情况下,它会在大多数情况下忽略您请求的原点坐标,并将新窗口放在所需的位置而不是您要求它放置的位置。只有在映射(某处)时,您才可以使用XMoveWindow()移动它。

为了避免这种情况,您可以在窗口管理器中询问,或者在X11中说“提示”,“不,我希望您将窗口放在我要求的位置,而不是您要放置的位置”。您可以按以下顺序执行此操作:

(1)定义XSizeHints结构。 (2)使用您要指定的掩码设置此结构中的标志位 (3)填充相关论点 (4)在新创建的窗口上调用XSetNormalHints()(在映射之前)。

所以在C代码中你会这样做:

XSizeHints    my_hints = {0};

my_hints.flags  = PPosition | PSize;     /* I want to specify position and size */
my_hints.x      = wanted_x_origin;       /* The origin and size coords I want */
my_hints.y      = wanted_y_origin;
my_hints.width  = wanted_width;
my_hints.height = wanted_height;

XSetNormalHints(disp, new_window, &my_hints);  /* Where new_window is the new window */

然后映射它 - 希望 - 它会在你想要的地方。

答案 1 :(得分:1)

我通常首先声明XSizeHints,然后将x,y坐标等分配给hints

创建x窗口时可以

 XCreateSimpleWindow(display, 
                     DefaultRootWindow(display), 
                     hints.x, hints.y, 
                     hints.width,hints.height, 
                     borderWidth, 
                     blackPixel, whitePixel)

对于我来说,100%正确的窗口位置始终适用于我。

答案 2 :(得分:0)

我遇到了同样的问题。我刚开始使用X11。也许拥有更多经验的其他人可以澄清其工作原理(并且只是为XCreateSimpleWindow指定x,y)。

这是我的修复:

disp是你的显示,win0是你的canvas_window:

XMoveWindow(disp, win0, 200, 200);

XSync (disp, FALSE);


 ..... do something .....

XMoveWindow(disp, win0, 0, 0);

XSync (disp, FALSE);

... do something

当我运行此代码段时,窗口会移动。您需要通过XSync跟随XMoveWindow,以便正确处理请求(例如移动)。