From f19331879792758734abe8eacf2c29cd2d7e5417 Mon Sep 17 00:00:00 2001 From: Jon Date: Fri, 5 Jan 2024 12:19:45 +0000 Subject: [PATCH] With exception of window focus, make sure hotkeys are processed in the game thread --- GWToolboxdll/Windows/HotkeysWindow.cpp | 31 ++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/GWToolboxdll/Windows/HotkeysWindow.cpp b/GWToolboxdll/Windows/HotkeysWindow.cpp index eb590e569..767504f67 100644 --- a/GWToolboxdll/Windows/HotkeysWindow.cpp +++ b/GWToolboxdll/Windows/HotkeysWindow.cpp @@ -52,6 +52,24 @@ namespace { TBHotkey* current_hotkey = nullptr; + std::queue pending_hotkeys; + std::recursive_mutex pending_mutex; + void PushPendingHotkey(TBHotkey* hk) { + pending_mutex.lock(); + pending_hotkeys.push(hk); + pending_mutex.unlock(); + } + TBHotkey* PopPendingHotkey() { + TBHotkey* hk = nullptr; + pending_mutex.lock(); + if (pending_hotkeys.size()) { + hk = pending_hotkeys.front(); + pending_hotkeys.pop(); + } + pending_mutex.unlock(); + return hk; + } + bool loaded_action_labels = false; // NB: GetActionLabel_Func() must be called when we're in-game, because it relies on other gw modules being loaded internally. // Because we only draw this module when we're in-game, we just need to call this from the Draw() loop instead of on Initialise() @@ -187,6 +205,7 @@ namespace { if (!block_hotkeys && !hk->pressed && ((activated && hk->trigger_on_gain_focus) || (!activated && hk->trigger_on_lose_focus))) { + // Would be nice to use PushPendingHotkey here, but losing/gaining focus is a special case hk->pressed = true; current_hotkey = hk; hk->Execute(); @@ -599,10 +618,7 @@ bool HotkeysWindow::WndProc(const UINT Message, const WPARAM wParam, LPARAM) && !hk->pressed && keyData == hk->hotkey && modifier == hk->modifier) { - hk->pressed = true; - current_hotkey = hk; - hk->Toggle(); - current_hotkey = nullptr; + PushPendingHotkey(hk); if (hk->block_gw) { triggered = true; } @@ -655,4 +671,11 @@ void HotkeysWindow::Update(const float) hotkeys[i]->Execute(); } } + while (const auto hk = PopPendingHotkey()) { + hk->pressed = true; + current_hotkey = hk; + hk->Execute(); + current_hotkey = nullptr; + hk->pressed = false; + } }