[Xcb] Framebuffer size vs Window size.

Carlo Wood carlo at alinoe.com
Thu Jan 20 14:37:54 UTC 2022

On for example Apple's Retina Display, the window coordinates are not
the same as the size in pixels (ie the framebuffer that has to be
used with OpenGL or Vulkan etc).

As an example of how this is taken into account, we can look at how
imgui calculates the scale between the two:


    glfwGetWindowSize(bd->Window, &w, &h);
    glfwGetFramebufferSize(bd->Window, &display_w, &display_h);
    io.DisplaySize = ImVec2((float) w, (float) h);
    if (w > 0 && h > 0) {
        io.DisplayFramebufferScale = ImVec2((float) display_w / w, (float) display_h / h); }

which using glfw to get the window size and framebuffer size.

In implementation of glfwGetWindowSize on a linux box is basically _glfwGetWindowSizeX11;
and glfwGetFramebufferSize is _glfwGetFramebufferSizeX11.

The implementation of _glfwGetFramebufferSizeX11 is:

    void _glfwGetFramebufferSizeX11(_GLFWwindow* window, int* width, int* height)
        _glfwGetWindowSizeX11(window, width, height);

which makes the above scale *always* 1.

I am NOT using glfw, I just looked at how they did this because I couldn't find any
relevant documentation on this subject for xcb. But it is hard to believe that on X11
this scale is non-existant (or always 1).

I do not own a high-dpi monitor so I can't experiment with this.

I am using pure XCB. What would be the canonical way to get the windowsize
and framebuffer size of a given window?

I am currently using XCB_CONFIGURE_NOTIFY events that the X server is sending
me and assume that those report window coordinates. But what about the frame
buffer coordinates?

It is possible that this scale changes without a window resize. For example
when a window is dragged from a high-DPI monitor to a normal monitor or back.
What event would I receive for this and how would it tell me what the
new framebuffer size is?

Carlo Wood

PS To be complete (without that you have to look this up), the implementation
of _glfwGetWindowSizeX11 is:

    void _glfwGetWindowSizeX11(_GLFWwindow* window, int* width, int* height)
        XWindowAttributes attribs;
        XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs);

        if (width)
            *width = attribs.width;
        if (height)
            *height = attribs.height;

for which I guess that the xcb equivalent is xcb_get_geometry.

More information about the Xcb mailing list