winex11.drv: Fix xinerama_get_fullscreen_monitors() not working correctly with non-fullscreen rects.
xinerama_get_fullscreen_monitors() was supposed to be called with fullscreen rects. Thus, we could assume the monitor indices are all zero when there is only one monitor as an optimization. However, after baf65867, xinerama_get_fullscreen_monitors() can be called with non-fullscreen rects. So we need to remove the optimization so that it works correctly for non-fullscreen rects as well.
Fix the Guild Wars 2 game window having an offset in fullscreen mode.
-- v2: winex11.drv: Fix xinerama_get_fullscreen_monitors() not working correctly with non-fullscreen rects.
From: Zhiyi Zhang zzhang@codeweavers.com
xinerama_get_fullscreen_monitors() was supposed to be called with fullscreen rects. Thus, we could assume the monitor indices are all zero when there is only one monitor as an optimization. However, after baf65867, xinerama_get_fullscreen_monitors() can be called with non-fullscreen rects. So we need to remove the optimization so that it works correctly for non-fullscreen rects as well.
Fix the Guild Wars 2 game window having an offset in fullscreen mode. --- dlls/winex11.drv/window.c | 7 ++++--- dlls/winex11.drv/x11drv.h | 2 +- dlls/winex11.drv/xinerama.c | 17 +++++++---------- 3 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 546d2583639..0eddc40da0c 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1685,9 +1685,10 @@ static UINT window_update_client_config( struct x11drv_win_data *data ) * window rect will be repeatedly changed by the WM and the application, causing a flickering effect */ if (data->is_fullscreen) { - xinerama_get_fullscreen_monitors( &data->rects.visible, &old_generation, old_monitors ); - xinerama_get_fullscreen_monitors( &data->current_state.rect, &generation, monitors ); - if (!memcmp( old_monitors, monitors, sizeof(monitors) )) return 0; + if (xinerama_get_fullscreen_monitors( &data->rects.visible, &old_generation, old_monitors ) + && xinerama_get_fullscreen_monitors( &data->current_state.rect, &generation, monitors ) + && !memcmp( old_monitors, monitors, sizeof(monitors) )) + return 0; }
flags = SWP_NOACTIVATE | SWP_NOZORDER; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 431c8e750bd..309632d2c3b 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -746,7 +746,7 @@ extern POINT virtual_screen_to_root( INT x, INT y ); extern POINT root_to_virtual_screen( INT x, INT y ); extern RECT get_host_primary_monitor_rect(void); extern RECT get_work_area( const RECT *monitor_rect ); -extern void xinerama_get_fullscreen_monitors( const RECT *rect, unsigned int *generation, long *indices ); +extern BOOL xinerama_get_fullscreen_monitors( const RECT *rect, unsigned int *generation, long *indices ); extern void xinerama_init( unsigned int width, unsigned int height ); extern void init_recursive_mutex( pthread_mutex_t *mutex ); extern void init_icm_profile(void); diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index 5086f3ee766..4ab78d55a95 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -124,20 +124,16 @@ static inline int query_screens(void)
#endif /* SONAME_LIBXINERAMA */
-/* Get xinerama monitor indices required for _NET_WM_FULLSCREEN_MONITORS */ -void xinerama_get_fullscreen_monitors( const RECT *rect, unsigned int *generation, long *indices ) +/* Get xinerama monitor indices required for _NET_WM_FULLSCREEN_MONITORS. Return FALSE if rect is + * not fullscreen */ +BOOL xinerama_get_fullscreen_monitors( const RECT *rect, unsigned int *generation, long *indices ) { RECT window_rect, intersected_rect, monitor_rect; + BOOL ret = FALSE; POINT offset; INT i;
pthread_mutex_lock( &xinerama_mutex ); - if (nb_monitors == 1) - { - memset( indices, 0, sizeof(*indices) * 4 ); - *generation = xinerama_generation; - goto done; - }
/* Convert window rectangle to root coordinates */ offset = virtual_screen_to_root( rect->left, rect->top ); @@ -173,10 +169,11 @@ void xinerama_get_fullscreen_monitors( const RECT *rect, unsigned int *generatio } }
- if (indices[0] == -1) WARN("Failed to get xinerama fullscreen monitor indices.\n"); + if (indices[0] != -1 && indices[1] != -1 && indices[2] != -1 && indices[3] != -1) + ret = TRUE;
-done: pthread_mutex_unlock( &xinerama_mutex ); + return ret; }
static BOOL xinerama_get_gpus( struct x11drv_gpu **new_gpus, int *count, BOOL get_properties )
Rémi Bernon (@rbernon) commented about dlls/winex11.drv/xinerama.c:
} }
- if (indices[0] == -1) WARN("Failed to get xinerama fullscreen monitor indices.\n");
- if (indices[0] != -1 && indices[1] != -1 && indices[2] != -1 && indices[3] != -1)
ret = TRUE;
I think checking only the first one is enough, they either all -1 or are all initialized at once.