Hi, I have some EDA tools running on a Linux machine and display on my Windows PC using xorg-server-21.1.3 XWin multiwindow mode Sometimes the application window flickers forever for an unknown reason. The problem became more severe after my PC upgrade to Windows10.
Googling the problem, I did not find such issue reported. I decided to take advantage of open source nature and solve it by myself. After re-compiling and debugging, I found a calling loop triggered. Here I eliminate the detail of the cause. I may write later if someone requires. Knowing the root cause, I am now able to demonstrate the issue with a small test case as well as a patch that works for me. Both are attached below. SL The test case: ============== /* Compile : gcc -o flicker2 flicker2.c -lX11 */ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <stdio.h> #include <stdlib.h> #include <string.h> void SetMax(Display *dpy, Window win, int val) { XEvent xev; Atom wm_state = XInternAtom(dpy, "_NET_WM_STATE", False); Atom max_horz = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_HORZ", False); Atom max_vert = XInternAtom(dpy, "_NET_WM_STATE_MAXIMIZED_VERT", False); memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; xev.xclient.window = win; xev.xclient.message_type = wm_state; xev.xclient.format = 32; xev.xclient.data.l[0] = val; // _NET_WM_STATE_ADD or _NET_WM_STATE_REMOVE xev.xclient.data.l[1] = max_horz; xev.xclient.data.l[2] = max_vert; XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &xev); } int main(void) { Display *display; Window win; XEvent X; int screen; if (!(display = XOpenDisplay(NULL))) exit(1); screen = DefaultScreen(display); win = XCreateSimpleWindow(display, RootWindow(display, screen), 10, 10, 100, 100, 0, BlackPixel(display, screen), WhitePixel(display, screen)); XMapWindow(display, win); SetMax(display, win, 1); SetMax(display, win, 0); XSelectInput(display, win, KeyPressMask | StructureNotifyMask); while (1) { XNextEvent(display, &X); } XCloseDisplay(display); return 0; } ============== and the patch I have applied ======================= --- a/hw/xwin/winmultiwindowwm.c +++ b/hw/xwin/winmultiwindowwm.c @@ -153,6 +153,9 @@ static void static WMMsgNodePtr PopMessage(WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo); +static Bool + HaveMessage(WMMsgQueuePtr pQueue, UINT msg, xcb_window_t iWindow); + static Bool InitQueue(WMMsgQueuePtr pQueue); @@ -319,7 +322,6 @@ PopMessage(WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) return pNode; } -#if 0 /* * HaveMessage - */ @@ -331,12 +333,11 @@ HaveMessage(WMMsgQueuePtr pQueue, UINT msg, xcb_window_t iWindow) for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) { if (pNode->msg.msg == msg && pNode->msg.iWindow == iWindow) - return True; + return TRUE; } - return False; + return FALSE; } -#endif /* * InitQueue - Initialize the Window Manager message queue @@ -1173,7 +1174,9 @@ winMultiWindowWMProc(void *pArg) break; case WM_WM_CHANGE_STATE: - UpdateState(pWMInfo, pNode->msg.iWindow, pNode->msg.dwID); + if(!HaveMessage(&pWMInfo->wmMsgQueue, pNode->msg.msg, pNode->msg.iWindow)) + UpdateState(pWMInfo, pNode->msg.iWindow, pNode->msg.dwID); + break; default: ======================= -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple