From 993bf9da556573721f10454aff8824aa47aed806 Mon Sep 17 00:00:00 2001 From: Awawa <69086569+awawa-dev@users.noreply.github.com> Date: Sat, 4 Jan 2025 16:59:27 +0100 Subject: [PATCH] Windows: fix system suspend handling --- include/systray/Systray.h | 1 + .../suspend-handler/SuspendHandlerWindows.cpp | 25 +++++++++++++++++++ sources/systray/SystrayWindows.cpp | 15 +++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/systray/Systray.h b/include/systray/Systray.h index 5450e9fbd..319b134d2 100644 --- a/include/systray/Systray.h +++ b/include/systray/Systray.h @@ -72,6 +72,7 @@ struct SystrayMenu #ifdef _WIN32 HWND SystrayGetWindow(); + void SystrayAssignQueueHandler(std::function _queueHandler); #endif diff --git a/sources/suspend-handler/SuspendHandlerWindows.cpp b/sources/suspend-handler/SuspendHandlerWindows.cpp index 5c2644c05..adbb3f2f4 100644 --- a/sources/suspend-handler/SuspendHandlerWindows.cpp +++ b/sources/suspend-handler/SuspendHandlerWindows.cpp @@ -44,6 +44,27 @@ namespace { HWND handle = nullptr; + SuspendHandler* instance = nullptr; +} + +static void SuspendHandlerQueueHandler(WPARAM wparam) +{ + if (instance != nullptr) + { + MSG message{}; + QByteArray eventType; + + message.message = WM_POWERBROADCAST; + message.wParam = wparam; + + #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + long result = 0; + BLOCK_CALL_3(instance, nativeEventFilter, QByteArray, eventType, void*, &message, long*, &result); + #else + qintptr result = 0; + BLOCK_CALL_3(instance, nativeEventFilter, QByteArray, eventType, void*, &message, qintptr*, &result); + #endif + } } SuspendHandler::SuspendHandler(bool sessionLocker): @@ -51,7 +72,9 @@ SuspendHandler::SuspendHandler(bool sessionLocker): _notifyMonitorHandle(NULL), _sessionLocker(sessionLocker) { + instance = this; handle = SystrayGetWindow(); + SystrayAssignQueueHandler(SuspendHandlerQueueHandler); _notifyHandle = RegisterSuspendResumeNotification(handle, DEVICE_NOTIFY_WINDOW_HANDLE); if (_notifyHandle == NULL) @@ -78,6 +101,8 @@ SuspendHandler::SuspendHandler(bool sessionLocker): SuspendHandler::~SuspendHandler() { + instance = nullptr; + if (_notifyHandle != NULL) { UnregisterSuspendResumeNotification(_notifyHandle); diff --git a/sources/systray/SystrayWindows.cpp b/sources/systray/SystrayWindows.cpp index e0004acfd..301e28600 100644 --- a/sources/systray/SystrayWindows.cpp +++ b/sources/systray/SystrayWindows.cpp @@ -46,6 +46,7 @@ namespace std::list icons; std::list bitmaps; ULONG_PTR gdiToken = 0; + std::function queueHandler = nullptr; } HWND SystrayGetWindow() @@ -53,11 +54,23 @@ HWND SystrayGetWindow() return window; } +void SystrayAssignQueueHandler(std::function _queueHandler) +{ + queueHandler = _queueHandler; +} + static LRESULT CALLBACK _tray_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { switch (msg) { + case WM_POWERBROADCAST: + if (queueHandler != nullptr && (wparam == PBT_APMSUSPEND || wparam == PBT_APMRESUMESUSPEND || wparam == PBT_POWERSETTINGCHANGE)) + { + queueHandler(wparam); + } + return true; + case WM_CLOSE: DestroyWindow(hwnd); hwnd = nullptr; @@ -290,6 +303,8 @@ void SystrayUpdate(SystrayMenu *tray) void SystrayClose() { + queueHandler = nullptr; + if (systrayIcon.hIcon != nullptr) { Shell_NotifyIcon(NIM_DELETE, &systrayIcon);