fix stuck keys on ubuntu and on focus loss #142
In the `OnKeyDown` event handler, check if the key is actually pressed using `wxGetKeyState()`, because for some reason on Ubuntu 18 spurious events are generated when the key is not actually pressed. Also, if a game is paused by the frontend while a key is being pressed, the key will remain active for the game when unpaused. This is an issue because the key will likely be released outside of the game zone; therefore, we would not process the key release for the game itself. The same bug happens if clicking outside of the game zone while holding a key. For the case of a directional key, this means a continuous movement in the direction of the key pressed before the pause until the key is pressed and released.
This commit is contained in:
parent
3d57750c16
commit
b0ec84693e
|
@ -16,6 +16,9 @@
|
|||
#include "filters.h"
|
||||
#include "wxvbam.h"
|
||||
|
||||
// release all buttons currently pressed
|
||||
static void clear_input_press();
|
||||
|
||||
int emulating;
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(GameArea, wxPanel)
|
||||
|
@ -919,6 +922,12 @@ GameArea::~GameArea()
|
|||
}
|
||||
}
|
||||
|
||||
void GameArea::OnKillFocus(wxFocusEvent& ev)
|
||||
{
|
||||
clear_input_press();
|
||||
ev.Skip(true);
|
||||
}
|
||||
|
||||
void GameArea::Pause()
|
||||
{
|
||||
if (paused)
|
||||
|
@ -932,6 +941,11 @@ void GameArea::Pause()
|
|||
|
||||
paused = was_paused = true;
|
||||
|
||||
// when the game is paused like this, we should not allow any
|
||||
// input to remain pressed, because they could be released
|
||||
// outside of the game zone and we would not know about it.
|
||||
clear_input_press();
|
||||
|
||||
if (loaded != IMAGE_UNKNOWN)
|
||||
soundPause();
|
||||
}
|
||||
|
@ -1022,6 +1036,9 @@ void GameArea::OnIdle(wxIdleEvent& event)
|
|||
// the userdata is freed on disconnect/destruction
|
||||
this->Connect(wxEVT_SIZE, wxSizeEventHandler(GameArea::OnSize), NULL, this);
|
||||
|
||||
// we need to check if the buttons stayed pressed when focus the panel
|
||||
w->Connect(wxEVT_KILL_FOCUS, wxFocusEventHandler(GameArea::OnKillFocus), NULL, this);
|
||||
|
||||
w->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
||||
w->SetSize(wxSize(basic_width, basic_height));
|
||||
|
||||
|
@ -1141,6 +1158,16 @@ static uint32_t bmask[NUM_KEYS] = {
|
|||
|
||||
static wxJoyKeyBinding_v keys_pressed;
|
||||
|
||||
static void clear_input_press()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
joypress[i] = 0;
|
||||
}
|
||||
keys_pressed.clear();
|
||||
}
|
||||
|
||||
struct game_key {
|
||||
int player;
|
||||
int key_num;
|
||||
|
@ -1257,7 +1284,9 @@ static void draw_black_background(wxWindow* win) {
|
|||
|
||||
void GameArea::OnKeyDown(wxKeyEvent& ev)
|
||||
{
|
||||
if (process_key_press(true, ev.GetKeyCode(), ev.GetModifiers())) {
|
||||
// check if the key is pressed indeed and then process it
|
||||
wxKeyCode keyCode = (wxKeyCode)ev.GetKeyCode();
|
||||
if (wxGetKeyState(keyCode) && process_key_press(true, ev.GetKeyCode(), ev.GetModifiers())) {
|
||||
ev.Skip(false);
|
||||
ev.StopPropagation();
|
||||
wxWakeUpIdle();
|
||||
|
|
|
@ -621,6 +621,7 @@ protected:
|
|||
void PaintEv(wxPaintEvent& ev);
|
||||
void EraseBackground(wxEraseEvent& ev);
|
||||
void OnSize(wxSizeEvent& ev);
|
||||
void OnKillFocus(wxFocusEvent& ev);
|
||||
|
||||
#ifndef NO_FFMPEG
|
||||
MediaRecorder snd_rec, vid_rec;
|
||||
|
|
Loading…
Reference in New Issue