http://bugs.winehq.org/show_bug.cgi?id=31702
--- Comment #32 from voidcastr cephryx@gmx.net 2012-09-24 07:21:02 CDT --- This is really getting nasty...
Investigating X11DRV_ClipCursor led to the following results:
When pressing a mouse button (activating raw input), the method seems to get triggered twice: 1. it calls ungrab_clipping_window() and returns because GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId() 2. it returns because EqualRect( clip, &clip_rect ) || clip_fullscreen_window( foreground, TRUE ) ...so data->clip_hwnd is non-NULL then.
When moving the mouse with the button pressed, X11DRV_ClipCursor is not called.
When releasing the mouse button (disabling raw input), to following happens in the given order: 1. X11DRV_ClipCursor returns because EqualRect( clip, &clip_rect ) || clip_fullscreen_window( foreground, TRUE ) ...so data->clip_hwnd is still non-NULL. 2. it calls ungrab_clipping_window() and then returns because !clip 3. it returns because GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId() 4. the method runs to its end and triggers ungrab_clipping_window() because !data->clip_hwnd
When then moving the mouse without a button pressed, the following two cases constantly take turns (this matches the steps #3 and #4 from above): 1. the method returns because GetWindowThreadProcessId( GetDesktopWindow(), NULL ) == GetCurrentThreadId() 2. the method runs to its end and triggers ungrab_clipping_window() because !data->clip_hwnd
Thus, your assumption
It would get set to NULL by ungrab_clipping_window()
seems to be correct.
Furthermore, I added traces to the end of all returns in grab_clipping_window, like if(!data->clip_hwnd) TRACE("bad clip_hwnd\n"); but they never occur.