win32u: Send display change messages when host display mode changes.

Similarly to when it is changed from an application call, but avoid
broadcasting WM_DISPLAYCHANGE to all windows when called from the
drivers, as we may have done it already.
This commit is contained in:
Rémi Bernon 2024-06-03 12:40:46 +02:00 committed by Alexandre Julliard
parent e54bb48eb8
commit 0a2ae3c41d
6 changed files with 53 additions and 34 deletions

View file

@ -3203,6 +3203,50 @@ static BOOL all_detached_settings( const DEVMODEW *displays )
return TRUE;
}
static BOOL get_primary_source_mode( DEVMODEW *mode )
{
struct source *primary;
BOOL ret;
if (!(primary = find_source( NULL ))) return FALSE;
ret = source_get_current_settings( primary, mode );
source_release( primary );
return ret;
}
static void display_mode_changed( BOOL broadcast )
{
DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)};
if (!update_display_cache( TRUE ))
{
ERR( "Failed to update display cache after mode change.\n" );
return;
}
if (!get_primary_source_mode( &current_mode ))
{
ERR( "Failed to get primary source current display settings.\n" );
return;
}
if (!broadcast)
send_message( get_desktop_window(), WM_DISPLAYCHANGE, current_mode.dmBitsPerPel,
MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ) );
else
{
/* broadcast to all the windows as well if an application changed the display settings */
NtUserClipCursor( NULL );
send_notify_message( get_desktop_window(), WM_DISPLAYCHANGE, current_mode.dmBitsPerPel,
MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ), FALSE );
send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, current_mode.dmBitsPerPel,
MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ),
SMTO_ABORTIFHUNG, 2000, FALSE );
/* post clip_fullscreen_window request to the foreground window */
NtUserPostMessage( NtUserGetForegroundWindow(), WM_WINE_CLIPCURSOR, SET_CURSOR_FSCLIP, 0 );
}
}
static LONG apply_display_settings( struct source *target, const DEVMODEW *devmode,
HWND hwnd, DWORD flags, void *lparam )
{
@ -3270,26 +3314,7 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo
}
}
if (!update_display_cache( TRUE ))
WARN( "Failed to update display cache after mode change.\n" );
if ((source = find_source( NULL )))
{
DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)};
if (!source_get_current_settings( source, &current_mode )) WARN( "Failed to get primary source current display settings.\n" );
source_release( source );
NtUserClipCursor( NULL );
send_notify_message( NtUserGetDesktopWindow(), WM_DISPLAYCHANGE, current_mode.dmBitsPerPel,
MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ), FALSE );
send_message_timeout( HWND_BROADCAST, WM_DISPLAYCHANGE, current_mode.dmBitsPerPel,
MAKELPARAM( current_mode.dmPelsWidth, current_mode.dmPelsHeight ),
SMTO_ABORTIFHUNG, 2000, FALSE );
/* post clip_fullscreen_window request to the foreground window */
NtUserPostMessage( NtUserGetForegroundWindow(), WM_WINE_CLIPCURSOR, SET_CURSOR_FSCLIP, 0 );
}
display_mode_changed( TRUE );
return ret;
}
@ -6306,8 +6331,9 @@ ULONG_PTR WINAPI NtUserCallNoParam( ULONG code )
case NtUserCallNoParam_ReleaseCapture:
return release_capture();
case NtUserCallNoParam_UpdateDisplayCache:
return update_display_cache( TRUE );
case NtUserCallNoParam_DisplayModeChanged:
display_mode_changed( FALSE );
return TRUE;
/* temporary exports */
case NtUserExitingThread:

View file

@ -84,7 +84,7 @@ void init_monitors( int width, int height )
wine_dbgstr_rect( &rect ), wine_dbgstr_rect( &monitor_rc_work ));
/* if we're notified from Java thread, update registry */
if (*p_java_vm) NtUserCallNoParam( NtUserCallNoParam_UpdateDisplayCache );
if (*p_java_vm) NtUserCallNoParam( NtUserCallNoParam_DisplayModeChanged );
}

View file

@ -1112,10 +1112,7 @@ void macdrv_displays_changed(const macdrv_event *event)
process it (by sending it to the desktop window). */
if (event->displays_changed.activating ||
NtUserGetWindowThread(hwnd, NULL) == GetCurrentThreadId())
{
NtUserCallNoParam(NtUserCallNoParam_UpdateDisplayCache);
macdrv_resize_desktop();
}
NtUserCallNoParam(NtUserCallNoParam_DisplayModeChanged);
}
UINT macdrv_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, void *param)

View file

@ -633,8 +633,7 @@ LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
switch (msg)
{
case WM_WAYLAND_INIT_DISPLAY_DEVICES:
NtUserCallNoParam(NtUserCallNoParam_UpdateDisplayCache);
wayland_resize_desktop();
NtUserCallNoParam(NtUserCallNoParam_DisplayModeChanged);
return 0;
case WM_WAYLAND_CONFIGURE:
wayland_configure_window(hwnd);

View file

@ -1180,10 +1180,7 @@ static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event )
xrandr14_invalidate_current_mode_cache();
if (hwnd == NtUserGetDesktopWindow() && NtUserGetWindowThread( hwnd, NULL ) == GetCurrentThreadId())
{
NtUserCallNoParam( NtUserCallNoParam_UpdateDisplayCache );
X11DRV_resize_desktop();
}
NtUserCallNoParam( NtUserCallNoParam_DisplayModeChanged );
/* Update xinerama monitors for xinerama_get_fullscreen_monitors() */
rect = get_host_primary_monitor_rect();
xinerama_init( rect.right - rect.left, rect.bottom - rect.top );

View file

@ -833,7 +833,7 @@ enum
NtUserCallNoParam_GetShellWindow,
NtUserCallNoParam_GetTaskmanWindow,
NtUserCallNoParam_ReleaseCapture,
NtUserCallNoParam_UpdateDisplayCache,
NtUserCallNoParam_DisplayModeChanged,
/* temporary exports */
NtUserExitingThread,
NtUserThreadDetach,