cubuntux11

X11: ConfigureNotify returns wrong window position on Ubuntu 24.04, works on 14.04


I've noticed that X11's ConfigureNotify event reports a wrong window position on Ubuntu 24.04. The same code works fine on Ubuntu 14.04 (and many other Linux distros). I first thought that maybe Ubuntu 24.04 uses Wayland and some sort of Wayland-->X11 wrapper that could explain the bogus values I'm getting but that's not the case. I've checked in the system settings and it uses X11 so Wayland can't be the culprit.

Here is my test code. Note that I'm setting the window position three times to make sure it really goes through ;) The first time is in XCreateWindow, then I use XSetWMNormalHints and finally I use XMoveWindow... see below...

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/X.h>

#define XPOS 300
#define YPOS 400

int main(int argc, char **argv)
{
    Display *disp = XOpenDisplay(0);
    Window rootWnd = DefaultRootWindow(disp);
    int screen = DefaultScreen(disp);
    int depth = DefaultDepth(disp, screen);
    Visual *vis = DefaultVisual(disp, screen);

    XSetWindowAttributes setWndAttr = {0};
    setWndAttr.event_mask = StructureNotifyMask;

    Window wnd = XCreateWindow(disp,rootWnd,XPOS,YPOS,640,480,0,depth,InputOutput,vis,CWEventMask,&setWndAttr);

    XStoreName(disp,wnd,"Test");

    XSizeHints *sh = XAllocSizeHints();
        
    sh->flags = PPosition;
    sh->x = XPOS;
    sh->y = YPOS;
        
    XSetWMNormalHints(disp, wnd, sh);
    XFree(sh);

    XMoveWindow(disp,wnd,XPOS,YPOS);
    XMapWindow(disp,wnd);

    Atom closeWndAtom = XInternAtom(disp,"WM_DELETE_WINDOW",0);
    XSetWMProtocols(disp,wnd,&closeWndAtom,1);

    int run = 1;
    XEvent evt;
    while(run) {
        XNextEvent(disp,&evt);
        switch(evt.type) {
        case ConfigureNotify: {         
            XConfigureEvent *ce = (XConfigureEvent *) &evt; 
            printf("ConfigureNotify: %d %d\n", ce->x, ce->y);
            break;      
            }
        case ClientMessage:
            run = 0;
            break;
        }
    }

    XDestroyWindow(disp,wnd);
    XCloseDisplay(disp);
    return 0;
}

On Ubuntu 14.04 the output is:

ConfigureNotify: 300 400
ConfigureNotify: 300 400
ConfigureNotify: 300 428

This is about right. Granted, the last reported position is shifted 28 pixels to the south which could be some sort of title bar adjustment but that's fine with me because the location is pretty close to what I requested.

On Ubuntu 24.04, however, the reported position is totally off. On Ubuntu 24.04 I get this:

ConfigureNotify: 14 49

This looks completely wrong to me. Is this a bug in Ubuntu 24's X11 or am I doing something wrong here? How can I get ConfigureNotify to report the correct position on Ubuntu 24.04 please?

EDIT: I should add that when I drag the window around using the mouse the reported position values are correct also on Ubuntu 24.04. It's really just the initial ConfigureNotify sent when the window is opened that contains bogus values.


Solution

  • Based on the documentation ConfigureNotify Events: "The x and y members are set to the coordinates relative to the parent window's origin...". It seems that the lower values are the decoration margins and you should always receive those values, never the position of the parent.

    In addition, it doesn't matter if you set the program specified position of the window, according to Setting and Reading the WM_NORMAL_HINTS Property: "The x, y, width, and height members are now obsolete and are left solely for compatibility reasons...".

    To translate a coordinate in one window to the coordinate space of another window, use XTranslateCoordinates.

    So in your case:

    XTranslateCoordinates(disp, wnd, rootWnd, 0, 0, &dx, &dy, &win);