无法让 XCreateSimpleWindow 在正确的位置打开窗口 [英] Cannot get XCreateSimpleWindow to open window at the right position

查看:19
本文介绍了无法让 XCreateSimpleWindow 在正确的位置打开窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The following code opens a window of the right size, w,h, but not at the correct position, 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 下运行.

I compiled this with g++ xwindowtest.cpp -lX11 where g++ is version 4.6.2 and ran under Debian GNU/Linux.

推荐答案

上述解决方案是正确的,但并不完整.

The above solution is sort of correct, but not complete.

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

Creating a new top-level window on the desktop, and creating a new (child) window within the top-level window of your application use the same XCreateSimpleWindow() call, but the actual behaviour can be different.

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

When creating a new child window within your application you are in charge, and the origin coordinates (relative to its parent window's origin) and size you give for the new window will be honoured. In other words the window will go where you want it to.

但是在桌面上创建新的顶级窗口时,您必须处理讨厌的窗口管理器,例如 Motif、KDE、Gnome 等.这会在您创建顶级窗口以添加边框时进行干预(装饰")、标题、可能的图标等.更重要的是,在大多数情况下,默认情况下,它会忽略您请求的原点坐标,并将新窗口放在它想要的位置,而不是您要求它放置的位置.只有当它被映射(某处)时,您才能使用 XMoveWindow() 移动它.

However when creating a new top-level window on the desktop you have to deal with the pesky window manager, for example Motif, KDE, Gnome, etc. This intervenes when you create a top-level window to add borders ("decoration"), title, possibly icons, etc. More to the point it will, by default, ignore your requested origin coordinates in most cases and put the new window where it wants rather than where you asked it to put it. It is only when it has been mapped (somewhere) that you can then move it with XMoveWindow().

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

To avoid this you can ask, or in X11-speak "Hint to", the Window manager that "no, I want you to put the window where I ask, not where you want to put it". You do this with the following sequence:

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

(1) Define a XSizeHints structure. (2) Set the flags bit in this structure with a mask of what you want to specify (3) Populate the relevant arguments (4) Call XSetNormalHints() on the newly created window (before you map it).

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

So in C code you would do:

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 */

然后将其映射并-希望-它将在您想要的位置.

Then map it and - hopefully - it will be where you want it.

这篇关于无法让 XCreateSimpleWindow 在正确的位置打开窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆