diff --git a/src/blackinput/keyboard.cpp b/src/blackinput/keyboard.cpp index 135125cbe..929fafa82 100644 --- a/src/blackinput/keyboard.cpp +++ b/src/blackinput/keyboard.cpp @@ -41,12 +41,4 @@ namespace BlackInput return m_instance; } - bool operator==(IKeyboard::RegistrationHandle const &lhs, IKeyboard::RegistrationHandle const &rhs) - { - if ((lhs.m_key == rhs.m_key) && (lhs.m_receiver == rhs.m_receiver)) - return true; - else - return false; - } - } // BlackInput diff --git a/src/blackinput/keyboard.h b/src/blackinput/keyboard.h index dd94c321b..9284acfc2 100644 --- a/src/blackinput/keyboard.h +++ b/src/blackinput/keyboard.h @@ -10,7 +10,7 @@ #ifndef BLACKINPUT_KEYBOARD_H #define BLACKINPUT_KEYBOARD_H -#include "../blackmisc/hwkeyboardkey.h" +#include "blackmisc/hwkeyboardkeylist.h" #include #include #include @@ -27,17 +27,6 @@ namespace BlackInput Q_OBJECT public: - //! \brief Handle to a registered hotkey function - struct RegistrationHandle - { - //! \brief Constructor - RegistrationHandle() {} - - BlackMisc::Hardware::CKeyboardKey m_key; //!< Registered key set - QPointer m_receiver; //!< Registered receiver - std::function function; //!< Registered function - }; - //! Operation mode enum Mode { @@ -51,64 +40,7 @@ namespace BlackInput //! Destructor virtual ~IKeyboard() {} - //! Creates a native keyboard handler object - static IKeyboard *getInstance(); - - /*! - * \brief Register a invokable slot as hotkey target - * \param key - * \param receiver - * \param slotName - * \return RegistrationHandle - */ - IKeyboard::RegistrationHandle registerHotkey(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, const QByteArray &slotName) - { - auto function = [=](bool isPressed){ QMetaObject::invokeMethod(receiver, slotName, Q_ARG(bool, isPressed)); }; - return registerHotkeyImpl(key, receiver, function); - } - - /*! - * \brief Register a member function as hotkey target - * \param key - * \param receiver - * \param slotPointer - * \return RegistrationHandle - */ - template - IKeyboard::RegistrationHandle registerHotkey(BlackMisc::Hardware::CKeyboardKey key, T *receiver, void (T:: *slotPointer)(bool)) - { - using namespace std::placeholders; - auto function = std::bind(slotPointer, receiver, _1); - return registerHotkeyImpl(key, receiver, function); - } - - /*! - * \brief Register a function object as hotkey target - * \param key - * \param receiver - * \param functionObject - * \return RegistrationHandle - */ - template - IKeyboard::RegistrationHandle registerHotkey(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, F functionObject) - { - return registerHotkeyImpl(key, receiver, functionObject); - } - - /*! - * \brief Unregister hotkey target - * \param handle - */ - void unregisterHotkey(const IKeyboard::RegistrationHandle &handle) - { - unregisterHotkeyImpl(handle); - } - - //! \brief Unregister all hotkeys - void unregisterAllHotkeys() - { - unregisterAllHotkeysImpl(); - } + virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) = 0; /*! * \brief Select a key combination as hotkey. This method returns immediatly. @@ -120,12 +52,6 @@ namespace BlackInput */ virtual void startCapture(bool ignoreNextKey) = 0; - /*! - * \brief Returns the amount of registered hotkey functions - * \return Size - */ - virtual int sizeOfRegisteredFunctions() const = 0; - /*! * \brief Triggers a key event manually and calls the registered functions. * \param key @@ -133,6 +59,9 @@ namespace BlackInput */ virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) = 0; + //! Creates a native keyboard handler object + static IKeyboard *getInstance(); + signals: /*! @@ -147,6 +76,9 @@ namespace BlackInput */ void keySelectionFinished(BlackMisc::Hardware::CKeyboardKey key); + void keyDown(const BlackMisc::Hardware::CKeyboardKey &); + void keyUp(const BlackMisc::Hardware::CKeyboardKey &); + protected: /*! @@ -154,31 +86,10 @@ namespace BlackInput */ virtual bool init() = 0; - /*! - * \brief Register implementation - */ - virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) = 0; - - /*! - * \brief Unregister implementation - */ - virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) = 0; - - //! \brief Unregister implementation - virtual void unregisterAllHotkeysImpl() = 0; - private: static IKeyboard *m_instance; }; - - /*! - * \brief Equal operator == - * \param lhs - * \param rhs - * \return - */ - bool operator==(IKeyboard::RegistrationHandle const &lhs, IKeyboard::RegistrationHandle const &rhs); } #endif // BLACKINPUT_KEYBOARD_H diff --git a/src/blackinput/linux/keyboard_linux.cpp b/src/blackinput/linux/keyboard_linux.cpp index 21bd79dcd..6999c4a59 100644 --- a/src/blackinput/linux/keyboard_linux.cpp +++ b/src/blackinput/linux/keyboard_linux.cpp @@ -38,6 +38,11 @@ namespace BlackInput return true; } + void CKeyboardLinux::setKeysToMonitor(const CKeyboardKeyList &keylist) + { + m_listMonitoredKeys = keylist; + } + void CKeyboardLinux::startCapture(bool ignoreNextKey) { m_mode = Mode_Capture; @@ -45,63 +50,9 @@ namespace BlackInput m_pressedKey.setKeyObject(CKeyboardKey()); } - int CKeyboardLinux::sizeOfRegisteredFunctions() const { - int size = 0; - foreach (QList functions, m_registeredFunctions) - { - size += functions.size(); - } - return size; - } - - void CKeyboardLinux::triggerKey(const CKeyboardKey key, bool isPressed) - { - callFunctionsBy(key, isPressed); - } - - IKeyboard::RegistrationHandle CKeyboardLinux::registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) - { - IKeyboard::RegistrationHandle handle; - - // Workaround: Remove key function. Otherwise operator== will not - // work when we create the key value object by pressed keys - key.setFunction(BlackMisc::Hardware::CKeyboardKey::HotkeyNone); - - if (!key.hasModifier() && !key.hasKey()) - { - return handle; - } - - if (receiver == nullptr) - return handle; - - // FIXME. Remove virtual key code, because the one we receive from Qt is different to the linux native code. - // If we don't remove it, the hash lookup fails later. - key.setNativeVirtualKey(0); - - handle.m_key = key; - handle.m_receiver = receiver; - handle.function = function; - - QList functions = m_registeredFunctions.value(key); - - functions.append(handle); - m_registeredFunctions.insert(key, functions); - - return handle; - } - - void CKeyboardLinux::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) - { - QList functions = m_registeredFunctions.value(handle.m_key); - functions.removeAll(handle); - m_registeredFunctions.insert(handle.m_key, functions); - } - - void CKeyboardLinux::unregisterAllHotkeysImpl() - { - m_registeredFunctions.clear(); + if(!isPressed) emit keyUp(key); + else emit keyDown(key); } void CKeyboardLinux::deviceDirectoryChanged(const QString &dir) @@ -166,19 +117,6 @@ namespace BlackInput emit keySelectionChanged(key); } - void CKeyboardLinux::callFunctionsBy(const CKeyboardKey &key, bool isPressed) - { - QList functionHandles = m_registeredFunctions.value(key); - foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles) - { - if (functionHandle.m_receiver.isNull()) - { - continue; - } - functionHandle.function(isPressed); - } - } - #define test_bit(bit, array) (array[bit/8] & (1<<(bit%8))) void CKeyboardLinux::addRawInputDevice(const QString &filePath) @@ -269,8 +207,8 @@ namespace BlackInput } else { - callFunctionsBy(lastPressedKey, false); - callFunctionsBy(m_pressedKey, true); + if (m_listMonitoredKeys.contains(lastPressedKey)) emit keyUp(lastPressedKey); + if (m_listMonitoredKeys.contains(m_pressedKey)) emit keyDown(m_pressedKey); } } } diff --git a/src/blackinput/linux/keyboard_linux.h b/src/blackinput/linux/keyboard_linux.h index 5683ec9bb..0ec5ead86 100644 --- a/src/blackinput/linux/keyboard_linux.h +++ b/src/blackinput/linux/keyboard_linux.h @@ -11,7 +11,7 @@ #define BLACKINPUT_KEYBOARD_LINUX_H #include "blackinput/keyboard.h" -#include "blackmisc/hwkeyboardkey.h" +#include "blackmisc/hwkeyboardkeylist.h" #include class QFileSystemWatcher; @@ -29,12 +29,12 @@ namespace BlackInput //! \brief Destructor virtual ~CKeyboardLinux(); + //! Set the list of keys to monitor + virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) override; + //! \copydoc IKeyboard::selectKey() virtual void startCapture(bool ignoreNextKey = false) override; - //! \copydoc IKeyboard::sizeOfRegisteredFunctions() - virtual int sizeOfRegisteredFunctions() const override; - //! \copydoc IKeyboard::triggerKey() virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) override; @@ -54,15 +54,6 @@ namespace BlackInput //! \brief Assignment operator void operator=(CKeyboardLinux const&); - //! \copydoc IKeyboard::registerHotKeyImpl() - virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) override; - - //! \copydoc IKeyboard::unregisterHotkeyImpl() - virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) override; - - //! \copydoc IKeyboard::unregisterHotkeyImpl() - virtual void unregisterAllHotkeysImpl() override; - private slots: //! Changed directory to linux devices @@ -80,13 +71,6 @@ namespace BlackInput */ void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished); - /*! - * \brief Calls registered functions on keyboard event - * \param keySet - * \param isPressed - */ - void callFunctionsBy(const BlackMisc::Hardware::CKeyboardKey &keySet, bool isPressed); - /*! * \brief Add new raw input device * \param filePath Path to device file @@ -100,8 +84,7 @@ namespace BlackInput */ void keyEvent(int virtualKeyCode, bool isPressed); - - QHash> m_registeredFunctions; //!< Registered hotkey functions + BlackMisc::Hardware::CKeyboardKeyList m_listMonitoredKeys; //!< Registered keys BlackMisc::Hardware::CKeyboardKey m_pressedKey; //!< Set of virtual keys pressed in the last cycle bool m_ignoreNextKey; //!< Is true if the next key needs to be ignored Mode m_mode; //!< Operation mode diff --git a/src/blackinput/osx/keyboard_mac.cpp b/src/blackinput/osx/keyboard_mac.cpp index f8add041c..3be18dd58 100644 --- a/src/blackinput/osx/keyboard_mac.cpp +++ b/src/blackinput/osx/keyboard_mac.cpp @@ -25,6 +25,11 @@ namespace BlackInput return true; } + void CKeyboardMac::setKeysToMonitor(const CKeyboardKeyList &keylist) + { + m_listMonitoredKeys = keylist; + } + void CKeyboardMac::startCapture(bool ignoreNextKey) { m_mode = Mode_Capture; @@ -32,59 +37,9 @@ namespace BlackInput m_pressedKey.setKeyObject(CKeyboardKey()); } - int CKeyboardMac::sizeOfRegisteredFunctions() const { - int size = 0; - foreach (QList functions, m_registeredFunctions) - { - size += functions.size(); - } - return size; - } - - void CKeyboardMac::triggerKey(const CKeyboardKey key, bool isPressed) - { - callFunctionsBy(key, isPressed); - } - - IKeyboard::RegistrationHandle CKeyboardMac::registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) - { - IKeyboard::RegistrationHandle handle; - - // Workaround: Remove key function. Otherwise operator== will not - // work when we create the key value object by pressed keys - key.setFunction(BlackMisc::Hardware::CKeyboardKey::HotkeyNone); - - if (!key.hasModifier() && !key.hasKey()) - { - return handle; - } - - if (receiver == nullptr) - return handle; - - handle.m_key = key; - handle.m_receiver = receiver; - handle.function = function; - - QList functions = m_registeredFunctions.value(key); - - functions.append(handle); - m_registeredFunctions.insert(key, functions); - - return handle; - } - - void CKeyboardMac::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) - { - QList functions = m_registeredFunctions.value(handle.m_key); - functions.removeAll(handle); - m_registeredFunctions.insert(handle.m_key, functions); - } - - void CKeyboardMac::unregisterAllHotkeysImpl() - { - m_registeredFunctions.clear(); + if(!isPressed) emit keyUp(key); + else emit keyDown(key); } void CKeyboardMac::sendCaptureNotification(const CKeyboardKey &key, bool isFinished) @@ -94,17 +49,4 @@ namespace BlackInput else emit keySelectionChanged(key); } - - void CKeyboardMac::callFunctionsBy(const CKeyboardKey &key, bool isPressed) - { - QList functionHandles = m_registeredFunctions.value(key); - foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles) - { - if (functionHandle.m_receiver.isNull()) - { - continue; - } - functionHandle.function(isPressed); - } - } } diff --git a/src/blackinput/osx/keyboard_mac.h b/src/blackinput/osx/keyboard_mac.h index f818525bd..c389d7ab6 100644 --- a/src/blackinput/osx/keyboard_mac.h +++ b/src/blackinput/osx/keyboard_mac.h @@ -11,7 +11,7 @@ #define BLACKINPUT_KEYBOARD_MAC_H #include "blackinput/keyboard.h" -#include "blackmisc/hwkeyboardkey.h" +#include "blackmisc/hwkeyboardkeylist.h" #include namespace BlackInput @@ -26,12 +26,12 @@ namespace BlackInput //! \brief Destructor virtual ~CKeyboardMac(); + //! Set the list of keys to monitor + virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) override; + //! \copydoc IKeyboard::selectKey() virtual void startCapture(bool ignoreNextKey = false) override; - //! \copydoc IKeyboard::sizeOfRegisteredFunctions() - virtual int sizeOfRegisteredFunctions() const override; - //! \copydoc IKeyboard::triggerKey() virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) override; @@ -51,15 +51,6 @@ namespace BlackInput //! \brief Assignment operator void operator=(CKeyboardMac const&); - //! \copydoc IKeyboard::registerHotKeyImpl() - virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) override; - - //! \copydoc IKeyboard::unregisterHotkeyImpl() - virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) override; - - //! \copydoc IKeyboard::unregisterHotkeyImpl() - virtual void unregisterAllHotkeysImpl() override; - private: /*! @@ -69,15 +60,7 @@ namespace BlackInput */ void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished); - /*! - * \brief Calls registered functions on keyboard event - * \param keySet - * \param isPressed - */ - void callFunctionsBy(const BlackMisc::Hardware::CKeyboardKey &keySet, bool isPressed); - - - QHash> m_registeredFunctions; //!< Registered hotkey functions + BlackMisc::Hardware::CKeyboardKeyList m_listMonitoredKeys; //!< Registered keys BlackMisc::Hardware::CKeyboardKey m_pressedKey; //!< Set of virtual keys pressed in the last cycle bool m_ignoreNextKey; //!< Is true if the next key needs to be ignored Mode m_mode; //!< Operation mode diff --git a/src/blackinput/win/keyboard_windows.cpp b/src/blackinput/win/keyboard_windows.cpp index 7c201f680..77bfe5585 100644 --- a/src/blackinput/win/keyboard_windows.cpp +++ b/src/blackinput/win/keyboard_windows.cpp @@ -30,6 +30,11 @@ namespace BlackInput return true; } + void CKeyboardWindows::setKeysToMonitor(const CKeyboardKeyList &keylist) + { + m_listMonitoredKeys = keylist; + } + void CKeyboardWindows::startCapture(bool ignoreNextKey) { m_mode = Mode_Capture; @@ -37,22 +42,13 @@ namespace BlackInput m_pressedKey.setKeyObject(CKeyboardKey()); } - int CKeyboardWindows::sizeOfRegisteredFunctions() const - { - int size = 0; - foreach (QList functions, m_registeredFunctions) - { - size += functions.size(); - } - return size; - } - void CKeyboardWindows::triggerKey(const CKeyboardKey key, bool isPressed) { - callFunctionsBy(key, isPressed); + if(!isPressed) emit keyUp(key); + else emit keyDown(key); } - void CKeyboardWindows::keyEvent(WPARAM vkcode, uint event) + void CKeyboardWindows::processKeyEvent(WPARAM vkcode, uint event) { BlackMisc::Hardware::CKeyboardKey lastPressedKey = m_pressedKey; if (m_ignoreNextKey) @@ -103,51 +99,11 @@ namespace BlackInput } else { - callFunctionsBy(lastPressedKey, false); - callFunctionsBy(m_pressedKey, true); + if (m_listMonitoredKeys.contains(lastPressedKey)) emit keyUp(lastPressedKey); + if (m_listMonitoredKeys.contains(m_pressedKey)) emit keyDown(m_pressedKey); } } - IKeyboard::RegistrationHandle CKeyboardWindows::registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) - { - IKeyboard::RegistrationHandle handle; - - // Workaround: Remove key function. Otherwise operator== will not - // work when we create the key value object by pressed keys - key.setFunction(BlackMisc::Hardware::CKeyboardKey::HotkeyNone); - - if (!key.hasModifier() && !key.hasKey()) - { - return handle; - } - - if (receiver == nullptr) - return handle; - - handle.m_key = key; - handle.m_receiver = receiver; - handle.function = function; - - QList functions = m_registeredFunctions.value(key); - - functions.append(handle); - m_registeredFunctions.insert(key, functions); - - return handle; - } - - void CKeyboardWindows::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) - { - QList functions = m_registeredFunctions.value(handle.m_key); - functions.removeAll(handle); - m_registeredFunctions.insert(handle.m_key, functions); - } - - void CKeyboardWindows::unregisterAllHotkeysImpl() - { - m_registeredFunctions.clear(); - } - void CKeyboardWindows::sendCaptureNotification(const CKeyboardKey &key, bool isFinished) { if (isFinished) @@ -156,27 +112,16 @@ namespace BlackInput emit keySelectionChanged(key); } - void CKeyboardWindows::callFunctionsBy(const CKeyboardKey &key, bool isPressed) - { - QList functionHandles = m_registeredFunctions.value(key); - foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles) - { - if (functionHandle.m_receiver.isNull()) - { - continue; - } - functionHandle.function(isPressed); - } - } - LRESULT CALLBACK CKeyboardWindows::keyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { + // This is the reason why we have to use singleton pattern. We cannot pass a object pointer to + // keyboardProc. CKeyboardWindows *keyboardWindows = qobject_cast(IKeyboard::getInstance()); if (nCode == HC_ACTION) { KBDLLHOOKSTRUCT *keyboardEvent =reinterpret_cast(lParam); WPARAM vkCode = keyboardEvent->vkCode; - keyboardWindows->keyEvent(vkCode, wParam); + keyboardWindows->processKeyEvent(vkCode, wParam); } return CallNextHookEx(keyboardWindows->keyboardHook(), nCode, wParam, lParam); } diff --git a/src/blackinput/win/keyboard_windows.h b/src/blackinput/win/keyboard_windows.h index aa504f390..13487ea16 100644 --- a/src/blackinput/win/keyboard_windows.h +++ b/src/blackinput/win/keyboard_windows.h @@ -12,6 +12,7 @@ #include "blackinput/keyboard.h" #include "blackmisc/hwkeyboardkey.h" +#include "blackmisc/hwkeyboardkeylist.h" #include #ifndef NOMINMAX #define NOMINMAX @@ -30,12 +31,12 @@ namespace BlackInput //! \brief Destructor virtual ~CKeyboardWindows(); + //! \copydoc IKeyboard::setKeysToMonitor() + virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) override; + //! \copydoc IKeyboard::selectKey() virtual void startCapture(bool ignoreNextKey = false) override; - //! \copydoc IKeyboard::sizeOfRegisteredFunctions() - virtual int sizeOfRegisteredFunctions() const override; - //! \copydoc IKeyboard::triggerKey() virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) override; @@ -43,7 +44,7 @@ namespace BlackInput HHOOK keyboardHook() const { return m_keyboardHook; } //! \private - void keyEvent(WPARAM vkCode, uint event); + void processKeyEvent(WPARAM vkCode, uint event); protected: @@ -61,15 +62,6 @@ namespace BlackInput //! \brief Assignment operator void operator=(CKeyboardWindows const&); - //! \copydoc IKeyboard::registerHotKeyImpl() - virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) override; - - //! \copydoc IKeyboard::unregisterHotkeyImpl() - virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) override; - - //! \copydoc IKeyboard::unregisterHotkeyImpl() - virtual void unregisterAllHotkeysImpl() override; - private: /*! @@ -79,13 +71,6 @@ namespace BlackInput */ void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished); - /*! - * \brief Calls registered functions on keyboard event - * \param keySet - * \param isPressed - */ - void callFunctionsBy(const BlackMisc::Hardware::CKeyboardKey &keySet, bool isPressed); - void addKey(WPARAM vkcode); void removeKey(WPARAM vkcode); @@ -99,7 +84,7 @@ namespace BlackInput static LRESULT CALLBACK keyboardProc(int nCode, WPARAM wParam, LPARAM lParam); - QHash> m_registeredFunctions; //!< Registered hotkey functions + BlackMisc::Hardware::CKeyboardKeyList m_listMonitoredKeys; //!< Registered keys BlackMisc::Hardware::CKeyboardKey m_pressedKey; //!< Set of virtual keys pressed in the last cycle bool m_ignoreNextKey; //!< Is true if the next key needs to be ignored HHOOK m_keyboardHook; //!< Keyboard hook handle