Skip to content
Permalink
Browse files

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.
  • Loading branch information
denisfa authored and rkitover committed May 29, 2019
1 parent 3d57750 commit b0ec84693eeac4ac37f12c381f5907c4c07c12b1
Showing with 31 additions and 1 deletion.
  1. +30 −1 src/wx/panel.cpp
  2. +1 −0 src/wx/wxvbam.h
@@ -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 @@ class GameArea : public wxPanel, public HiDPIAware {
void PaintEv(wxPaintEvent& ev);
void EraseBackground(wxEraseEvent& ev);
void OnSize(wxSizeEvent& ev);
void OnKillFocus(wxFocusEvent& ev);

#ifndef NO_FFMPEG
MediaRecorder snd_rec, vid_rec;

0 comments on commit b0ec846

Please sign in to comment.
You can’t perform that action at this time.