Check game kbd input with wxGetKeyState() again.

Followup on baa0341b.

Reintroduce checking if a key is actually pressed in the panel OnKeyDown
event with wxGetKeyState(key_code).

Introduced in b0ec846 and removed in baa0341b.

wxGetKeyState() does not work on Wayland and does not work for Unicode
keys, support for which was introduced in baa0341b, which is why the
call was removed.

Add two static functions is_key_pressed(ev) and is_key_released(ev) that
return true under Wayland or if the key is Unicode, and call
wxGetKeyState() otherwise.

The reason this call was introduced in b0ec846 was to work around a bug
in some Linux distributions that caused spurious keyboard events to be
generated. The bug apparently still persists, see #689.

Because the two additional checks were necessarily added, the bug may
persist on Wayland, if it exists there, and for Unicode keys, but will
be fixed in the more common case of Latin keys under Xorg.

Tested on Linux with both Latin and Unicode game input keyboard keys.

- Fix #689.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
This commit is contained in:
Rafael Kitover 2020-06-28 00:20:33 +00:00
parent 8e88363163
commit 306f92f5d7
1 changed files with 25 additions and 2 deletions

View File

@ -17,6 +17,7 @@
#include "filters.h"
#include "wxvbam.h"
#include "wxutil.h"
#include "wayland.h"
#ifdef __WXMSW__
#include <windows.h>
@ -1312,10 +1313,32 @@ static void draw_black_background(wxWindow* win) {
dc.DrawRectangle(0, 0, w, h);
}
static bool is_key_pressed(wxKeyEvent& ev)
{
auto kc = ev.GetKeyCode();
// Under Wayland or if the key is unicode, we can't use wxGetKeyState().
if (IsItWayland() || kc == WXK_NONE)
return true;
return wxGetKeyState(static_cast<wxKeyCode>(kc));
}
static bool is_key_released(wxKeyEvent& ev)
{
auto kc = ev.GetKeyCode();
// Under Wayland or if the key is unicode, we can't use wxGetKeyState().
if (IsItWayland() || kc == WXK_NONE)
return true;
return !wxGetKeyState(static_cast<wxKeyCode>(kc));
}
void GameArea::OnKeyDown(wxKeyEvent& ev)
{
int kc = getKeyboardKeyCode(ev);
if (process_key_press(true, kc, ev.GetModifiers())) {
if (is_key_pressed(ev) && process_key_press(true, kc, ev.GetModifiers())) {
wxWakeUpIdle();
}
}
@ -1323,7 +1346,7 @@ void GameArea::OnKeyDown(wxKeyEvent& ev)
void GameArea::OnKeyUp(wxKeyEvent& ev)
{
int kc = getKeyboardKeyCode(ev);
if (process_key_press(false, kc, ev.GetModifiers())) {
if (is_key_released(ev) && process_key_press(false, kc, ev.GetModifiers())) {
wxWakeUpIdle();
}
}