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

标签 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 下运行。

最佳答案

上面的解决方案是正确的,但并不完整。

在桌面上创建新的顶级窗口,并在应用程序的顶级窗口中创建新的(子)窗口使用相同的 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 */

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

关于x11 - 无法让 XCreateSimpleWindow 在正确的位置打开窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11069666/

相关文章:

c - 检测 X11 窗口向顶部/左侧调整大小

c++ - 在 Linux 上使用 X11 抓取特定键上的事件

linux - Linux 上的 X11 网络

在 Xlib 中捕获按钮事件,然后将事件传递给客户端

Linux x11 XGrabKeyboard() 导致键盘被卡住

c++ - 创建没有标题栏的窗口

linux - Motif Widget Toolkit 的 Perl 绑定(bind)

linux - MOTIF 编程和 X11 客户端?

linux - 如何查看linux X11版本?

opengl - Vulkan 和 X11 Pixmap