[PATCH 1/2] winex11.drv: Resize desktop upon display change events.

Zhiyi Zhang zzhang at codeweavers.com
Mon May 11 03:55:27 CDT 2020


Otherwise, Wine still has the old desktop size after a user changed
display resolution using host system utilities.

X11DRV_DisplayDevices_Update() is introduced so that display devices
reinitialization is separated from desktop resizing. Otherwise,
X11DRV_DisplayDevices_Init() would have to be called twice to resize
the desktop with up-to-date primary monitor dimensions, wasting resources.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48441
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/winex11.drv/desktop.c  | 37 ++++++++++++++++++++-----------------
 dlls/winex11.drv/display.c  | 18 ++++++++++++++++++
 dlls/winex11.drv/window.c   |  2 +-
 dlls/winex11.drv/x11drv.h   |  3 ++-
 dlls/winex11.drv/xrandr.c   | 11 ++++++++---
 dlls/winex11.drv/xvidmode.c |  2 +-
 6 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c
index bde4841ed42..9011f50c20c 100644
--- a/dlls/winex11.drv/desktop.c
+++ b/dlls/winex11.drv/desktop.c
@@ -145,7 +145,10 @@ static LONG X11DRV_desktop_SetCurrentMode(int mode)
          */
     }
     TRACE("Resizing Wine desktop window to %dx%d\n", dd_modes[mode].width, dd_modes[mode].height);
-    X11DRV_resize_desktop(dd_modes[mode].width, dd_modes[mode].height);
+
+    desktop_width = dd_modes[mode].width;
+    desktop_height = dd_modes[mode].height;
+    X11DRV_DisplayDevices_Update( TRUE );
     return DISP_CHANGE_SUCCESSFUL;
 }
 
@@ -387,35 +390,35 @@ static void update_desktop_fullscreen( unsigned int width, unsigned int height)
 /***********************************************************************
  *		X11DRV_resize_desktop
  */
-void X11DRV_resize_desktop( unsigned int width, unsigned int height )
+void X11DRV_resize_desktop( UINT mask, BOOL send_display_change )
 {
-    RECT old_virtual_rect, new_virtual_rect;
+    RECT primary_rect, virtual_rect;
     HWND hwnd = GetDesktopWindow();
-    UINT mask = 0;
+    INT width, height;
 
-    old_virtual_rect = get_virtual_screen_rect();
-    desktop_width = width;
-    desktop_height = height;
-    X11DRV_DisplayDevices_Init( TRUE );
-    new_virtual_rect = get_virtual_screen_rect();
-
-    if (old_virtual_rect.left != new_virtual_rect.left) mask |= CWX;
-    if (old_virtual_rect.top != new_virtual_rect.top) mask |= CWY;
+    virtual_rect = get_virtual_screen_rect();
+    primary_rect = get_primary_monitor_rect();
+    width = primary_rect.right;
+    height = primary_rect.bottom;
 
     if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId())
     {
-        SendMessageW( hwnd, WM_X11DRV_RESIZE_DESKTOP, 0, MAKELPARAM( width, height ) );
+        SendMessageW( hwnd, WM_X11DRV_RESIZE_DESKTOP, (WPARAM)mask, (LPARAM)send_display_change );
     }
     else
     {
         TRACE( "desktop %p change to (%dx%d)\n", hwnd, width, height );
         update_desktop_fullscreen( width, height );
-        SetWindowPos( hwnd, 0, new_virtual_rect.left, new_virtual_rect.top,
-                      new_virtual_rect.right - new_virtual_rect.left, new_virtual_rect.bottom - new_virtual_rect.top,
+        SetWindowPos( hwnd, 0, virtual_rect.left, virtual_rect.top,
+                      virtual_rect.right - virtual_rect.left, virtual_rect.bottom - virtual_rect.top,
                       SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE );
         ungrab_clipping_window();
-        SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp,
-                             MAKELPARAM( width, height ), SMTO_ABORTIFHUNG, 2000, NULL );
+
+        if (send_display_change)
+        {
+            SendMessageTimeoutW( HWND_BROADCAST, WM_DISPLAYCHANGE, screen_bpp, MAKELPARAM( width, height ),
+                                 SMTO_ABORTIFHUNG, 2000, NULL );
+        }
     }
 
     EnumWindows( update_windows_on_desktop_resize, (LPARAM)mask );
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 4429cb89224..503f8c96877 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -273,6 +273,24 @@ void X11DRV_DisplayDevices_RegisterEventHandlers(void)
         handler->register_event_handlers();
 }
 
+void X11DRV_DisplayDevices_Update(BOOL send_display_change)
+{
+    RECT old_virtual_rect, new_virtual_rect;
+    UINT mask = 0;
+
+    old_virtual_rect = get_virtual_screen_rect();
+    X11DRV_DisplayDevices_Init(TRUE);
+    new_virtual_rect = get_virtual_screen_rect();
+
+    /* Calculate XReconfigureWMWindow() mask */
+    if (old_virtual_rect.left != new_virtual_rect.left)
+        mask |= CWX;
+    if (old_virtual_rect.top != new_virtual_rect.top)
+        mask |= CWY;
+
+    X11DRV_resize_desktop(mask, send_display_change);
+}
+
 /* Initialize a GPU instance and return its GUID string in guid_string and driver value in driver parameter */
 static BOOL X11DRV_InitGpu(HDEVINFO devinfo, const struct x11drv_gpu *gpu, INT gpu_index, WCHAR *guid_string,
                            WCHAR *driver)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index c773c278b72..ca40005d729 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2729,7 +2729,7 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
         }
         return 0;
     case WM_X11DRV_RESIZE_DESKTOP:
-        X11DRV_resize_desktop( LOWORD(lp), HIWORD(lp) );
+        X11DRV_resize_desktop( (UINT)wp, (BOOL)lp );
         return 0;
     case WM_X11DRV_SET_CURSOR:
         if ((data = get_win_data( hwnd )))
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 98cab8947be..1f8af184808 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -657,7 +657,7 @@ struct x11drv_mode_info
 };
 
 extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) DECLSPEC_HIDDEN;
-extern void X11DRV_resize_desktop(unsigned int width, unsigned int height) DECLSPEC_HIDDEN;
+extern void X11DRV_resize_desktop(UINT, BOOL) DECLSPEC_HIDDEN;
 extern BOOL is_virtual_desktop(void) DECLSPEC_HIDDEN;
 extern BOOL is_desktop_fullscreen(void) DECLSPEC_HIDDEN;
 extern BOOL create_desktop_win_data( Window win ) DECLSPEC_HIDDEN;
@@ -755,6 +755,7 @@ struct x11drv_display_device_handler
 extern void X11DRV_DisplayDevices_SetHandler(const struct x11drv_display_device_handler *handler) DECLSPEC_HIDDEN;
 extern void X11DRV_DisplayDevices_Init(BOOL force) DECLSPEC_HIDDEN;
 extern void X11DRV_DisplayDevices_RegisterEventHandlers(void) DECLSPEC_HIDDEN;
+extern void X11DRV_DisplayDevices_Update(BOOL) DECLSPEC_HIDDEN;
 /* Display device handler used in virtual desktop mode */
 extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN;
 
diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c
index 95e4a5d6dba..76e76806c55 100644
--- a/dlls/winex11.drv/xrandr.c
+++ b/dlls/winex11.drv/xrandr.c
@@ -209,7 +209,7 @@ static LONG xrandr10_set_current_mode( int mode )
     if (stat == RRSetConfigSuccess)
     {
         xrandr_current_mode = mode;
-        X11DRV_resize_desktop( dd_modes[mode].width, dd_modes[mode].height );
+        X11DRV_DisplayDevices_Update( TRUE );
         return DISP_CHANGE_SUCCESSFUL;
     }
 
@@ -457,7 +457,7 @@ static LONG xrandr12_set_current_mode( int mode )
     }
 
     xrandr_current_mode = mode;
-    X11DRV_resize_desktop( dd_modes[mode].width, dd_modes[mode].height );
+    X11DRV_DisplayDevices_Update( TRUE );
     return DISP_CHANGE_SUCCESSFUL;
 }
 
@@ -1094,7 +1094,12 @@ static void xrandr14_free_monitors( struct x11drv_monitor *monitors )
 static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event )
 {
     if (hwnd == GetDesktopWindow() && GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
-        X11DRV_DisplayDevices_Init( TRUE );
+    {
+        /* Don't send a WM_DISPLAYCHANGE message here because this event may be a result from
+         * ChangeDisplaySettings(). Otherwise, ChangeDisplaySettings() would send multiple
+         * WM_DISPLAYCHANGE messages instead of just one */
+        X11DRV_DisplayDevices_Update( FALSE );
+    }
     return FALSE;
 }
 
diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c
index 890dbc46c71..a5884543163 100644
--- a/dlls/winex11.drv/xvidmode.c
+++ b/dlls/winex11.drv/xvidmode.c
@@ -145,7 +145,7 @@ static LONG X11DRV_XF86VM_SetCurrentMode(int mode)
   XWarpPointer(gdi_display, None, DefaultRootWindow(gdi_display), 0, 0, 0, 0, 0, 0);
 #endif
   XSync(gdi_display, False);
-  X11DRV_resize_desktop( real_xf86vm_modes[mode]->hdisplay, real_xf86vm_modes[mode]->vdisplay );
+  X11DRV_DisplayDevices_Update( TRUE );
   return DISP_CHANGE_SUCCESSFUL;
 }
 
-- 
2.25.1




More information about the wine-devel mailing list