From c42900f959fd75037006a2b2448f83e409813b93 Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Fri, 5 Oct 2018 13:32:01 +0200 Subject: [PATCH] Release input devices when application is shutdown If they are released with the deallocation of CInputManager, we might run into global deallocation hell. Also on Windows release all DirectX devices before COM library is closed. ref T391 --- src/blackcore/application.cpp | 5 +++++ src/blackcore/inputmanager.cpp | 6 ++++++ src/blackcore/inputmanager.h | 3 +++ src/blackinput/win/joystickwindows.cpp | 2 ++ src/blackinput/win/joystickwindows.h | 6 +++--- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/blackcore/application.cpp b/src/blackcore/application.cpp index 6748ce520..540c00fdb 100644 --- a/src/blackcore/application.cpp +++ b/src/blackcore/application.cpp @@ -19,6 +19,7 @@ #include "blackcore/registermetadata.h" #include "blackcore/setupreader.h" #include "blackcore/webdataservices.h" +#include "blackcore/inputmanager.h" #include "blackmisc/atomicfile.h" #include "blackmisc/applicationinfo.h" #include "blackmisc/datacache.h" @@ -975,6 +976,10 @@ namespace BlackCore // info that we will shutdown emit this->aboutToShutdown(); + // Release all input devices to not cause any accidental hotkey triggers anymore. + // This is also necessary to properly free platform specific instances at a defined point in time. + CInputManager::instance()->releaseDevices(); + // mark as shutdown if (m_networkWatchDog) { m_networkWatchDog->gracefulShutdown(); } m_shutdown = true; diff --git a/src/blackcore/inputmanager.cpp b/src/blackcore/inputmanager.cpp index 35d3bbc5e..9bcfd3c76 100644 --- a/src/blackcore/inputmanager.cpp +++ b/src/blackcore/inputmanager.cpp @@ -129,6 +129,12 @@ namespace BlackCore m_lastCombination = combination; } + void CInputManager::releaseDevices() + { + m_keyboard.reset(); + m_joystick.reset(); + } + int CInputManager::bindImpl(const QString &action, QObject *receiver, std::function function) { static int index = 0; diff --git a/src/blackcore/inputmanager.h b/src/blackcore/inputmanager.h index db126ac23..e5a2cd952 100644 --- a/src/blackcore/inputmanager.h +++ b/src/blackcore/inputmanager.h @@ -87,6 +87,9 @@ namespace BlackCore //! Triggers a key event manually and calls the registered functions. void triggerKey(const BlackMisc::Input::CHotkeyCombination &combination, bool isPressed); + //! Releases all devices + void releaseDevices(); + //! Creates a native keyboard handler object static CInputManager *instance(); diff --git a/src/blackinput/win/joystickwindows.cpp b/src/blackinput/win/joystickwindows.cpp index 4ff95e043..99fac783f 100644 --- a/src/blackinput/win/joystickwindows.cpp +++ b/src/blackinput/win/joystickwindows.cpp @@ -165,6 +165,8 @@ namespace BlackInput CJoystickWindows::~CJoystickWindows() { + m_joystickDevices.clear(); + m_directInput.reset(); CoUninitialize(); } diff --git a/src/blackinput/win/joystickwindows.h b/src/blackinput/win/joystickwindows.h index bb1103d23..e95583f8f 100644 --- a/src/blackinput/win/joystickwindows.h +++ b/src/blackinput/win/joystickwindows.h @@ -134,13 +134,13 @@ namespace BlackInput ATOM helperWindowClass = 0; HWND helperWindow = nullptr; + const TCHAR *helperWindowClassName = TEXT("HelperWindow"); + const TCHAR *helperWindowName = TEXT("JoystickCatcherWindow"); + DirectInput8Ptr m_directInput; //!< DirectInput object QVector m_joystickDevices; //!< Joystick devices BlackMisc::Input::CHotkeyCombination m_buttonCombination; - - const TCHAR *helperWindowClassName = TEXT("HelperWindow"); - const TCHAR *helperWindowName = TEXT("JoystickCatcherWindow"); }; } // ns