Otherwise, the client rect in [needs_client_window_clipping](https://gitlab.winehq.org/wine/wine/-/blob/3f7ff8b5896394a3edd2d3d49f6d118f8...) is outdated, which can result in offscreening when it's not necessary or vice-versa.
This keeps the intention of 54d82ed4d5483f7569871219acc485b3cb5a224e while restoring the previous behavior.
-- v2: winex11: Use the win32 client rect in needs_client_window_clipping.
From: William Horvath william@horvath.blog
After the change to move the sync_gl_drawable call outside the win_data mutex in 54d82ed4, the X11 client rect used for determining whether we need to composite/clip the drawable can be out of sync with the win32 side. This results in offscreening when unnecessary and vice-versa. --- dlls/winex11.drv/init.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 71c50df95e6..0670eb16d54 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -196,15 +196,12 @@ static HFONT X11DRV_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
static BOOL needs_client_window_clipping( HWND hwnd ) { - struct x11drv_win_data *data; RECT rect, client; UINT ret = 0; HRGN region; HDC hdc;
- if (!(data = get_win_data( hwnd ))) return TRUE; - client = data->rects.client; - release_win_data( data ); + NtUserGetClientRect( hwnd, &client, NtUserGetDpiForWindow( hwnd ) ); OffsetRect( &client, -client.left, -client.top );
if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE ))) return FALSE;
On Tue Jan 7 08:25:21 2025 +0000, Rémi Bernon wrote:
We could probably call `NtUserGetClientRect` in `needs_client_window_clipping` instead, this should work all the time and could be arguably more consistent with the region check which also uses win32u info.
That seems much less prone to races and does the trick.
This merge request was approved by Rémi Bernon.
Rémi Bernon (@rbernon) commented about dlls/winex11.drv/init.c:
struct x11drv_win_data *data; RECT rect, client; UINT ret = 0; HRGN region; HDC hdc;
if (!(data = get_win_data( hwnd ))) return TRUE;
client = data->rects.client;
release_win_data( data );
NtUserGetClientRect( hwnd, &client, NtUserGetDpiForWindow( hwnd ) ); OffsetRect( &client, -client.left, -client.top );
if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE ))) return FALSE; if ((region = NtGdiCreateRectRgn( 0, 0, 0, 0 ))) { ret = NtGdiGetRandomRgn( hdc, region, SYSRGN | NTGDI_RGN_MONITOR_DPI );
Actually, you need to either use `NtUserGetWinMonitorDpi` here, or remove `NTGDI_RGN_MONITOR_DPI` from the `NtGdiGetRandomRgn` call. The latter being possibly better as it will avoid any rounding and the eventually related issues.
On Tue Jan 7 08:36:35 2025 +0000, Rémi Bernon wrote:
Actually, you need to either use `NtUserGetWinMonitorDpi` here, or remove `NTGDI_RGN_MONITOR_DPI` from the `NtGdiGetRandomRgn` call. The latter being possibly better as it will avoid any rounding and the eventually related issues.
I missed that, but doesn't the `NtUserGetDpiForWindow( hwnd ) != NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI )` check in `needs_offscreen_rendering` already prevent this from being an issue?
Regardless, I'll remove the `NTGDI_RGN_MONITOR_DPI` flag, in case the function is used somewhere else in the future.
On Tue Jan 7 08:44:16 2025 +0000, William Horvath wrote:
I missed that, but doesn't the `NtUserGetDpiForWindow( hwnd ) != NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI )` check in `needs_offscreen_rendering` already prevent this from being an issue? Regardless, I'll remove the `NTGDI_RGN_MONITOR_DPI` flag, in case the function is used somewhere else in the future.
Yes, you're right that it's prevented but yes, it's better to be consistent in isolation.