如何使用 X11lib 以编程方式调整 window 的大小?

How to resize a window programmatically with X11lib?

我正在创建一个 X11 window,然后使用 XWindowResize:

以编程方式调整其大小
#include <X11/Xlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <cassert>
#include <cstdio>

int main()
{
    Display* display = XOpenDisplay(nullptr);
    assert(display);

    Window root = DefaultRootWindow(display);
    assert(root);

    GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
    XVisualInfo* vi = glXChooseVisual(display, 0, att);
    assert(vi);

    XSetWindowAttributes swa;
    swa.colormap = XCreateColormap(display, root, vi->visual, AllocNone);
    swa.event_mask = ExposureMask | KeyPressMask;

    // create window with initial size 800 x 600
    Window window = XCreateWindow(display, root, 0, 0, 800, 600, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
    XSelectInput(display, window, StructureNotifyMask | ResizeRedirectMask);
    XMapWindow(display, window);
    XFlush(display);

    // resize window to new size 400 x 300
    int result = XResizeWindow(display, window, 400, 300);
    printf("XResizeWindow  return value: %d\n", result);
    if (result == BadValue) printf("   bad value!!!\n");
    if (result == BadWindow) printf("   bad window!!!\n");

    XEvent event;
    XAnyEvent& ev = (XAnyEvent&)event;
    while (true)
    {
        XNextEvent(display, &event);

        if (ev.type == ResizeRequest)
        {
            XResizeRequestEvent& ev = (XResizeRequestEvent&)event;
            printf("request to resize to %d x %d\n", ev.width, ev.height);
        }

        XWindowAttributes xwa;
        XGetWindowAttributes(display, window, &xwa);
        printf("position: %d, %d     size: %d x %d\n", xwa.x, xwa.y, xwa.width, xwa.height);
    }
}

这没有按预期工作。 window 管理器绘制的 window 装饰表明它确实被调整为 400x300 像素,但是,XGetWindowAttributes 报告相反(下面的输出)。使用鼠标手动更改位置和大小具有相同的效果:调整大小请求报告正确的大小,但未反映在 XGetWindowAttributes 的输出中。问题是这会影响检测到鼠标事件的区域以及 OpenGL 绘图(已删除以提供最小示例)。

XResizeWindow  return value: 1
position: 1, 30     size: 800 x 600
position: 1, 30     size: 800 x 600
request to resize to 400 x 300
position: 1, 30     size: 800 x 600
position: 1, 30     size: 800 x 600
position: 1, 30     size: 800 x 600

显然我做错了。对于如何完成这项工作,我将不胜感激。我是否必须执行任何操作才能满足调整大小请求?我已经在网上和 Whosebug 上搜索了几个小时,但没有成功。

编辑: 如果有人能告诉我 XResizeWindow return 值 1 是否表示错误,那将会很有帮助。如果没有错误,我无法找到有关 return 值的文档。此外,非常欢迎包含此信息的文档链接!

不要请求 ResizeRedirectMask。它应该一次由一个客户请求,通常是您的 window 经理。除了 WM 通常在根节点上请求 SubstructureNotifyMaks,它优先于子节点上的 ResizeRedirectMask,因此后者毫无用处。我找不到一个使用 ResizeRedirectMask.

的程序示例,WM 或其他程序

如果您请求 ResizeRedirectMask,您的 window 属性可能会卡住错误的尺寸。

如果您需要捕获实际尺寸变化,请请求 StructureNotifyMask 并处理 ConfigureNotify 个事件。