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/base/AccessManager.cpp b/sources/base/AccessManager.cpp index 344882557..022ad939c 100644 --- a/sources/base/AccessManager.cpp +++ b/sources/base/AccessManager.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace hyperhdr; diff --git a/sources/db/AuthTable.cpp b/sources/db/AuthTable.cpp index 8fe5281af..77fd7278d 100644 --- a/sources/db/AuthTable.cpp +++ b/sources/db/AuthTable.cpp @@ -1,4 +1,5 @@ #include +#include #include using namespace hyperhdr; diff --git a/sources/db/MetaTable.cpp b/sources/db/MetaTable.cpp index 4be49be1c..ba7259eaa 100644 --- a/sources/db/MetaTable.cpp +++ b/sources/db/MetaTable.cpp @@ -1,5 +1,6 @@ #include #include +#include #include diff --git a/sources/led-drivers/net/DriverNetUdpE131.cpp b/sources/led-drivers/net/DriverNetUdpE131.cpp index 3c3e9fa40..6b77b0e3d 100644 --- a/sources/led-drivers/net/DriverNetUdpE131.cpp +++ b/sources/led-drivers/net/DriverNetUdpE131.cpp @@ -5,6 +5,7 @@ #endif #include +#include // hyperhdr local includes #include diff --git a/sources/suspend-handler/SuspendHandlerWindows.cpp b/sources/suspend-handler/SuspendHandlerWindows.cpp index 5c2644c05..d886c6383 100644 --- a/sources/suspend-handler/SuspendHandlerWindows.cpp +++ b/sources/suspend-handler/SuspendHandlerWindows.cpp @@ -38,12 +38,39 @@ #include #include #include +#include #pragma comment (lib, "WtsApi32.Lib") namespace { HWND handle = nullptr; + SuspendHandler* instance = nullptr; +} + +static void SuspendHandlerQueueHandler(WPARAM wparam) +{ + if (wparam == 0) + { + auto instance = QCoreApplication::instance(); + QUEUE_CALL_0(instance, quit); + } + else 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 +78,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 +107,9 @@ SuspendHandler::SuspendHandler(bool sessionLocker): SuspendHandler::~SuspendHandler() { + SystrayAssignQueueHandler(nullptr); + instance = nullptr; + if (_notifyHandle != NULL) { UnregisterSuspendResumeNotification(_notifyHandle); diff --git a/sources/systray/SystrayWindows.cpp b/sources/systray/SystrayWindows.cpp index e0004acfd..0d455b1a9 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,30 @@ 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_QUERYENDSESSION: + if (queueHandler != nullptr && lparam == 0) + { + queueHandler(0); + } + return false; + case WM_CLOSE: DestroyWindow(hwnd); hwnd = nullptr; @@ -290,6 +310,8 @@ void SystrayUpdate(SystrayMenu *tray) void SystrayClose() { + queueHandler = nullptr; + if (systrayIcon.hIcon != nullptr) { Shell_NotifyIcon(NIM_DELETE, &systrayIcon);