[PATCH v2] wined3d: Inhibit the screensaver while a full-screen application has focus.

Zebediah Figura zfigura at codeweavers.com
Mon Jul 29 14:14:19 CDT 2019


This matches Windows behaviour at least as of Windows 7.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
Windows does not seem to do it using SystemParametersInfo(), nor using
SetThreadExecutionState(). I suspect it is instead using the Power*Request()
APIs, but as far as I'm aware implementing those would require getting at an
external library such as X11 or dbus from ntdll (or kernel32), which is not
permitted.

 dlls/wined3d/device.c          | 6 ++++++
 dlls/wined3d/swapchain.c       | 2 ++
 dlls/wined3d/wined3d_private.h | 3 ++-
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index a4c26cf3976..ab4a6ce9400 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1023,6 +1023,8 @@ void CDECL wined3d_device_restore_fullscreen_window(struct wined3d_device *devic
 
 HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device, HWND window)
 {
+    UINT screensaver_active;
+
     TRACE("device %p, window %p.\n", device, window);
 
     if (!wined3d_register_window(NULL, window, device, 0))
@@ -1033,6 +1035,9 @@ HRESULT CDECL wined3d_device_acquire_focus_window(struct wined3d_device *device,
 
     InterlockedExchangePointer((void **)&device->focus_window, window);
     SetWindowPos(window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
+    SystemParametersInfoW(SPI_GETSCREENSAVEACTIVE, 0, &screensaver_active, 0);
+    device->restore_screensaver = !!screensaver_active;
+    SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
 
     return WINED3D_OK;
 }
@@ -1043,6 +1048,7 @@ void CDECL wined3d_device_release_focus_window(struct wined3d_device *device)
 
     if (device->focus_window) wined3d_unregister_window(device->focus_window);
     InterlockedExchangePointer((void **)&device->focus_window, NULL);
+    SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, device->restore_screensaver, NULL, 0);
 }
 
 static void device_init_swapchain_state(struct wined3d_device *device, struct wined3d_swapchain *swapchain)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 8603c8de7a0..6534fe28cb0 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1148,6 +1148,8 @@ void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activa
     if (!focus_messages)
         device->filter_messages = 1;
 
+    SystemParametersInfoW(SPI_SETSCREENSAVEACTIVE, !activate && device->restore_screensaver, NULL, 0);
+
     if (activate)
     {
         if (!(device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES))
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b959a280608..56c7e0004d4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3171,7 +3171,8 @@ struct wined3d_device
     BYTE inScene : 1;                   /* A flag to check for proper BeginScene / EndScene call pairs */
     BYTE softwareVertexProcessing : 1;  /* process vertex shaders using software or hardware */
     BYTE filter_messages : 1;
-    BYTE padding : 3;
+    BYTE restore_screensaver : 1;
+    BYTE padding : 2;
 
     unsigned char           surface_alignment; /* Line Alignment of surfaces                      */
 
-- 
2.20.1




More information about the wine-devel mailing list