From 8a6b9152985ed346afa56a1c09079f2cd9bfdcaf Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 5 Nov 2014 05:46:09 +0100 Subject: fix keyboard shortcuts on win32 change during tracking Used to become unusable if changed during tracking. --- opentrack/shortcuts.cpp | 43 +++++++++++++++++++++++++++++++------------ opentrack/shortcuts.h | 46 +++++++++++++++++++++++++++++----------------- opentrack/work.hpp | 4 ++-- 3 files changed, 62 insertions(+), 31 deletions(-) (limited to 'opentrack') diff --git a/opentrack/shortcuts.cpp b/opentrack/shortcuts.cpp index 75b86a29..88c6c69d 100644 --- a/opentrack/shortcuts.cpp +++ b/opentrack/shortcuts.cpp @@ -1,4 +1,5 @@ #include "shortcuts.h" +#include KeyboardShortcutDialog::KeyboardShortcutDialog() { @@ -39,6 +40,14 @@ void KeyboardShortcutDialog::doCancel() { #if defined(_WIN32) #include +void KeybindingWorker::set_keys(Key kCenter_, Key kToggle_) +{ + QMutexLocker l(&mtx); + + kCenter = kCenter_; + kToggle = kToggle_; +} + KeybindingWorker::~KeybindingWorker() { should_quit = true; wait(); @@ -50,8 +59,8 @@ KeybindingWorker::~KeybindingWorker() { din->Release(); } -KeybindingWorker::KeybindingWorker(Key keyCenter, Key keyToggle, WId handle) : - din(0), dinkeyboard(0), kCenter(keyCenter), kToggle(keyToggle), should_quit(true) +KeybindingWorker::KeybindingWorker(Key keyCenter, Key keyToggle, WId handle, Shortcuts& sc) : + sc(sc), din(0), dinkeyboard(0), kCenter(keyCenter), kToggle(keyToggle), should_quit(true) { if (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&din, NULL) != DI_OK) { qDebug() << "setup DirectInput8 Creation failed!" << GetLastError(); @@ -111,12 +120,9 @@ static bool isKeyPressed( const Key *key, const BYTE *keystate ) { return false; } -#define PROCESS_KEY(k, s) \ - if (isKeyPressed(&k, keystate) && (!k.ever_pressed ? (k.timer.start(), k.ever_pressed = true) : k.timer.restart() > 100)) \ - emit s; - void KeybindingWorker::run() { BYTE keystate[256]; + while (!should_quit) { if (dinkeyboard->GetDeviceState(256, (LPVOID)keystate) != DI_OK) { @@ -125,10 +131,16 @@ void KeybindingWorker::run() { continue; } - PROCESS_KEY(kCenter, center()); - PROCESS_KEY(kToggle, toggle()); + QMutexLocker l(&mtx); - Sleep(14); + if (isKeyPressed(&kCenter, keystate) && kCenter.should_process()) + emit sc.center(); + + if (isKeyPressed(&kToggle, keystate) && kToggle.should_process()) + emit sc.toggle(); + + // keypresses get dropped with high values + Sleep(15); } } #endif @@ -159,6 +171,7 @@ void Shortcuts::bind_keyboard_shortcut(K &key, key_opts& k) } } #else + key = K(); int idx = k.key_index; key.keycode = 0; key.shift = key.alt = key.ctrl = 0; @@ -169,6 +182,7 @@ void Shortcuts::bind_keyboard_shortcut(K &key, key_opts& k) key.ctrl = k.ctrl; #endif } + void Shortcuts::reload() { #ifndef _WIN32 if (keyCenter) @@ -185,8 +199,13 @@ void Shortcuts::reload() { bind_keyboard_shortcut(keyCenter, s.center); bind_keyboard_shortcut(keyToggle, s.toggle); #ifdef _WIN32 - keybindingWorker = nullptr; - keybindingWorker = std::make_shared(keyCenter, keyToggle, handle); - keybindingWorker->start(); + bool is_new = keybindingWorker == nullptr; + if (is_new) + { + keybindingWorker = std::make_shared(keyCenter, keyToggle, handle, *this); + keybindingWorker->start(); + } + else + keybindingWorker->set_keys(keyCenter, keyToggle); #endif } diff --git a/opentrack/shortcuts.h b/opentrack/shortcuts.h index a588b482..77e40180 100644 --- a/opentrack/shortcuts.h +++ b/opentrack/shortcuts.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -6,6 +7,7 @@ #include #include #include +#include #include "qxt-mini/QxtGlobalShortcut" #include "opentrack/plugin-support.h" @@ -41,42 +43,49 @@ struct Key { bool shift; bool ctrl; bool alt; - bool ever_pressed; QElapsedTimer timer; public: - Key() : keycode(0), shift(false), ctrl(false), alt(false), ever_pressed(false) + Key() : keycode(0), shift(false), ctrl(false), alt(false) { } + + bool should_process() + { + return !timer.isValid() ? (timer.start(), true) : timer.restart() > 100; + } }; #else typedef unsigned char BYTE; struct Key { int foo; }; #endif +class Shortcuts; + struct KeybindingWorker : public QThread { - Q_OBJECT #ifdef _WIN32 private: + Shortcuts& sc; LPDIRECTINPUT8 din; LPDIRECTINPUTDEVICE8 dinkeyboard; Key kCenter; Key kToggle; + QMutex mtx; public: volatile bool should_quit; ~KeybindingWorker(); - KeybindingWorker(Key keyCenter, Key keyToggle, WId handle); - void run(); + KeybindingWorker(Key keyCenter, Key keyToggle, WId handle, Shortcuts& sc); + void run(); + void set_keys(Key kCenter, Key kToggle); #else public: KeybindingWorker(Key, Key, WId) {} - void run() {} + void run() {} #endif -signals: - void center(); - void toggle(); }; -struct Shortcuts { +struct Shortcuts : public QObject { + Q_OBJECT + using K = #ifndef _WIN32 mem @@ -84,7 +93,7 @@ struct Shortcuts { Key #endif ; - + K keyCenter; K keyToggle; @@ -92,7 +101,8 @@ struct Shortcuts { #ifdef _WIN32 mem keybindingWorker; #endif - + +public: struct settings { pbundle b; key_opts center, toggle; @@ -110,20 +120,22 @@ struct Shortcuts { void reload(); private: void bind_keyboard_shortcut(K &key, key_opts& k); +signals: + void center(); + void toggle(); }; class KeyboardShortcutDialog: public QWidget { Q_OBJECT +signals: + void reload(); public: KeyboardShortcutDialog(); private: Ui::UICKeyboardShortcutDialog ui; Shortcuts::settings s; - mem sc; -signals: - void reload(); private slots: - void doOK(); - void doCancel(); + void doOK(); + void doCancel(); }; diff --git a/opentrack/work.hpp b/opentrack/work.hpp index bb9a4534..9a9889a7 100644 --- a/opentrack/work.hpp +++ b/opentrack/work.hpp @@ -27,8 +27,8 @@ struct Work QObject::connect(sc->keyCenter.get(), SIGNAL(activated()), recv, SLOT(shortcutRecentered())); QObject::connect(sc->keyToggle.get(), SIGNAL(activated()), recv, SLOT(shortcutToggled())); #else - QObject::connect(sc->keybindingWorker.get(), SIGNAL(center()), recv, SLOT(shortcutRecentered())); - QObject::connect(sc->keybindingWorker.get(), SIGNAL(toggle()), recv, SLOT(shortcutToggled())); + QObject::connect(sc.get(), SIGNAL(center()), recv, SLOT(shortcutRecentered())); + QObject::connect(sc.get(), SIGNAL(toggle()), recv, SLOT(shortcutToggled())); #endif tracker->start(); } -- cgit v1.2.3