Ubuntu 24.04下X11 ConfigureNotify事件返回错误窗口初始位置的问题求助
我遇到了一个奇怪的问题:Ubuntu 24.04上X11的ConfigureNotify事件返回的窗口初始位置完全不对,但同样的代码在Ubuntu 14.04(以及其他很多Linux发行版)上运行正常。
一开始我怀疑是Ubuntu 24.04默认用Wayland,可能是Wayland转X11的兼容层导致数值异常,但我检查了系统设置,确认当前会话用的是X11,所以Wayland不是问题根源。
为了复现问题,我特意写了一段测试代码——我三次设置窗口位置来确保生效:第一次在XCreateWindow里,然后用XSetWMNormalHints,最后调用XMoveWindow。代码如下:
#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; }
不同系统的输出对比
Ubuntu 14.04输出:
ConfigureNotify: 300 400
ConfigureNotify: 300 400
ConfigureNotify: 300 428
这个结果基本符合预期,最后一次的Y坐标偏移了28像素,应该是窗口标题栏的调整,这个我可以接受。Ubuntu 24.04输出:
ConfigureNotify: 14 49
这个数值完全偏离了我设置的300/400,看起来完全错误。
编辑补充:我后来发现,当用鼠标拖拽窗口移动时,Ubuntu 24.04上ConfigureNotify返回的位置值是正确的——只有窗口刚打开时发送的初始ConfigureNotify事件里的数值是错误的。
想问下这是Ubuntu 24.04的X11存在bug,还是我代码里有什么问题?有没有办法让Ubuntu 24.04上的ConfigureNotify返回正确的初始窗口位置?
内容来源于stack exchange

