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

Eka*_*vya 4 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
}
Run Code Online (Sandbox Code Playgroud)

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

小智 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 */
Run Code Online (Sandbox Code Playgroud)

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

  • ubuntu 10的行为是使用XCreateWindow中的原始x和y而不是wm_hints中的x和y(就像它只需要PPosition | PSize掩码,但不需要值)。精神病院级的东西。 (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
Run Code Online (Sandbox Code Playgroud)

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