From: Gabriel Ivăncescu gabrielopcode@gmail.com
When we are clipping (due to fullscreen), certain operations are bugged (such as creating another window on top, grabbing the window during a size-move operation, changing mouse capture, etc) so we must temporarily unclip first.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53831 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/winex11.drv/mouse.c | 13 ++++++++++++- dlls/winex11.drv/window.c | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 96be81df6e3..a51d697aef7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -557,6 +557,7 @@ BOOL clip_fullscreen_window( HWND hwnd, BOOL reset ) release_win_data( data ); if (!fullscreen) return FALSE; if (!(thread_data = x11drv_thread_data())) return FALSE; + if (thread_data->grab_hwnd) return FALSE; if (NtGetTickCount() - thread_data->clip_reset < 1000) return FALSE; if (!reset && clipping_cursor && thread_data->clip_hwnd) return FALSE; /* already clipping */
@@ -1641,6 +1642,7 @@ void move_resize_window( HWND hwnd, int dir ) POINT pos; int button = 0; XEvent xev; + BOOL was_clipped = FALSE; Window win, root, child; unsigned int xstate;
@@ -1670,7 +1672,15 @@ void move_resize_window( HWND hwnd, int dir )
/* need to ungrab the pointer that may have been automatically grabbed * with a ButtonPress event */ - XUngrabPointer( display, CurrentTime ); + if (!clipping_cursor) + XUngrabPointer( display, CurrentTime ); + + /* unclip it during drag, see Wine-Bug 53831 */ + if (x11drv_thread_data()->clip_hwnd) + { + was_clipped = TRUE; + ungrab_clipping_window(); + } XSendEvent(display, root_window, False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
/* try to detect the end of the size/move by polling for the mouse button to be released */ @@ -1713,6 +1723,7 @@ void move_resize_window( HWND hwnd, int dir ) if (!(xstate & (Button1Mask << (button - 1)))) break; NtUserMsgWaitForMultipleObjectsEx( 0, NULL, 100, QS_ALLINPUT, 0 ); } + if (was_clipped) grab_clipping_window( &clip_rect );
TRACE( "hwnd %p/%lx done\n", hwnd, win ); send_message( hwnd, WM_EXITSIZEMOVE, 0, 0 ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 70a29d24fb1..a0620d90d85 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1567,6 +1567,7 @@ static void create_whole_window( struct x11drv_win_data *data ) WCHAR text[1024]; COLORREF key; BYTE alpha; + BOOL was_clipped = FALSE; DWORD layered_flags; HRGN win_rgn; POINT pos; @@ -1595,10 +1596,21 @@ static void create_whole_window( struct x11drv_win_data *data ) if (!(cy = data->whole_rect.bottom - data->whole_rect.top)) cy = 1; else if (cy > 65535) cy = 65535;
+ /* unclip it while we create the Window, see Wine-Bug 53831 */ + if (x11drv_thread_data()->clip_hwnd) + { + was_clipped = TRUE; + ungrab_clipping_window(); + } pos = virtual_screen_to_root( data->whole_rect.left, data->whole_rect.top ); data->whole_window = XCreateWindow( data->display, root_window, pos.x, pos.y, cx, cy, 0, data->vis.depth, InputOutput, data->vis.visual, mask, &attr ); + if (was_clipped) + { + clipping_cursor = TRUE; + retry_grab_clipping_window(); + } if (!data->whole_window) goto done;
set_initial_wm_hints( data->display, data->whole_window ); @@ -2402,6 +2414,8 @@ void X11DRV_SetCapture( HWND hwnd, UINT flags ) if (!(data = get_win_data( NtUserGetAncestor( hwnd, GA_ROOT )))) return; if (data->whole_window) { + if (data->managed && thread_data->clip_hwnd) + ungrab_clipping_window(); XFlush( gdi_display ); XGrabPointer( data->display, data->whole_window, False, PointerMotionMask | ButtonPressMask | ButtonReleaseMask, @@ -2412,12 +2426,15 @@ void X11DRV_SetCapture( HWND hwnd, UINT flags ) } else /* release capture */ { - if (!(data = get_win_data( thread_data->grab_hwnd ))) return; + HWND grab_hwnd = thread_data->grab_hwnd; + + if (!(data = get_win_data( grab_hwnd ))) return; XFlush( gdi_display ); XUngrabPointer( data->display, CurrentTime ); XFlush( data->display ); thread_data->grab_hwnd = NULL; release_win_data( data ); + clip_fullscreen_window( grab_hwnd, FALSE ); } }