如何使用X11lib以编程方式调整窗口大小?

时间:2017-10-21 11:21:31

标签: c++ c resize x11

我正在创建一个X11窗口,然后使用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);
    }
}

这不按预期工作。窗口管理器绘制的窗口装饰表明它确实调整为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

显然我做错了。我很感激有关如何完成这项工作的任何帮助。为了兑现调整大小请求,我是否必须做任何事情?我已经搜索了网络和stackoverflow几个小时,但没有运气。

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

1 个答案:

答案 0 :(得分:1)

不要请求ResizeRedirectMask。它应该由一个客户一次请求,通常是您的窗口管理器。除了WM通常在根上请求SubstructureNotifyMaks,它优先于孩子的ResizeRedirectMask,因此后者是无用的。我找不到使用ResizeRedirectMask的程序WM或其他的一个例子。

如果您确实请求了ResizeRedirectMask,那么您的窗口属性可能会卡住错误的大小。

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