Windows: distinguish left and right modifiers

This is just some workaround until we either use a different input api for keyboards or until we refactor the keyboard_pad_handler to use Qt with native scan codes
This commit is contained in:
Megamouse 2020-06-22 20:19:02 +02:00
parent bec6bde919
commit b5f01372ee
3 changed files with 70 additions and 10 deletions

View File

@ -190,9 +190,8 @@ void keyboard_pad_handler::processKeyEvent(QKeyEvent* event, bool pressed)
return;
}
auto handleKey = [this, pressed, event]()
auto handle_key = [this, pressed, event]()
{
const QString name = qstr(GetKeyName(event));
QStringList list = GetKeyNames(event);
if (list.isEmpty())
return;
@ -201,6 +200,8 @@ void keyboard_pad_handler::processKeyEvent(QKeyEvent* event, bool pressed)
if (is_num_key)
list.removeAll("Num");
const QString name = qstr(GetKeyName(event));
// TODO: Edge case: switching numlock keeps numpad keys pressed due to now different modifier
// Handle every possible key combination, for example: ctrl+A -> {ctrl, A, ctrl+A}
@ -226,17 +227,17 @@ void keyboard_pad_handler::processKeyEvent(QKeyEvent* event, bool pressed)
case Qt::Key_L:
case Qt::Key_Return:
if (event->modifiers() != Qt::AltModifier)
handleKey();
handle_key();
break;
case Qt::Key_P:
case Qt::Key_S:
case Qt::Key_R:
case Qt::Key_E:
if (event->modifiers() != Qt::ControlModifier)
handleKey();
handle_key();
break;
default:
handleKey();
handle_key();
break;
}
event->ignore();
@ -472,6 +473,12 @@ QStringList keyboard_pad_handler::GetKeyNames(const QKeyEvent* keyEvent)
list.append(QKeySequence(keyEvent->key() | Qt::KeypadModifier).toString(QKeySequence::NativeText));
}
// Handle special cases
if (const std::string name = native_scan_code_to_string(keyEvent->nativeScanCode()); !name.empty())
{
list.append(qstr(name));
}
switch (keyEvent->key())
{
case Qt::Key_Alt:
@ -500,6 +507,12 @@ QStringList keyboard_pad_handler::GetKeyNames(const QKeyEvent* keyEvent)
std::string keyboard_pad_handler::GetKeyName(const QKeyEvent* keyEvent)
{
// Handle special cases first
if (const std::string name = native_scan_code_to_string(keyEvent->nativeScanCode()); !name.empty())
{
return name;
}
switch (keyEvent->key())
{
case Qt::Key_Alt:
@ -534,6 +547,8 @@ u32 keyboard_pad_handler::GetKeyCode(const QString& keyName)
{
if (keyName.isEmpty())
return 0;
else if (const int native_scan_code = native_scan_code_from_string(sstr(keyName)); native_scan_code >= 0)
return Qt::Key_unknown + native_scan_code; // Special cases that can't be expressed with Qt::Key
else if (keyName == "Alt")
return Qt::Key_Alt;
else if (keyName == "AltGr")
@ -546,14 +561,56 @@ u32 keyboard_pad_handler::GetKeyCode(const QString& keyName)
return Qt::Key_Meta;
QKeySequence seq(keyName);
u32 keyCode = 0;
u32 key_code = 0;
if (seq.count() == 1)
keyCode = seq[0];
key_code = seq[0];
else
input_log.notice("GetKeyCode(%s): seq.count() = %d", sstr(keyName), seq.count());
return keyCode;
return key_code;
}
int keyboard_pad_handler::native_scan_code_from_string(const std::string& key)
{
// NOTE: Qt throws a Ctrl key at us when using Alt Gr, so there is no point in distinguishing left and right Alt at the moment
#ifdef _WIN32
if (key == "Shift Left")
return 42;
else if (key == "Shift Right")
return 54;
else if (key == "Ctrl Left")
return 29;
else if (key == "Ctrl Right")
return 285;
#else
// TODO
#endif
return -1;
}
std::string keyboard_pad_handler::native_scan_code_to_string(int native_scan_code)
{
switch (native_scan_code)
{
#ifdef _WIN32
// NOTE: the other Qt function "nativeVirtualKey" does not distinguish between VK_SHIFT and VK_RSHIFT key in Qt at the moment
// NOTE: Qt throws a Ctrl key at us when using Alt Gr, so there is no point in distinguishing left and right Alt at the moment
case 42:
return "Shift Left";
case 54:
return "Shift Right";
case 29:
return "Ctrl Left";
case 285:
return "Ctrl Right";
#else
// TODO
// NOTE for MacOs: nativeScanCode may not work
#endif
default:
return "";
}
}
bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr<Pad> pad, const std::string& device)

View File

@ -93,6 +93,9 @@ public:
u32 GetKeyCode(const std::string& keyName);
u32 GetKeyCode(const QString& keyName);
static int native_scan_code_from_string(const std::string& key);
static std::string native_scan_code_to_string(int native_scan_code);
protected:
void Key(const u32 code, bool pressed, u16 value = 255);

View File

@ -106,8 +106,8 @@ void gs_frame::showEvent(QShowEvent *event)
{
// we have to calculate new window positions, since the frame is only known once the window was created
// the left and right margins are too big on my setup for some reason yet unknown, so we'll have to ignore them
int x = geometry().left(); //std::max(geometry().left(), frameMargins().left());
int y = std::max(geometry().top(), frameMargins().top());
const int x = geometry().left(); //std::max(geometry().left(), frameMargins().left());
const int y = std::max(geometry().top(), frameMargins().top());
setPosition(x, y);