[LINUX,WINDOWS] Key/Joy background input.
- Joystick background input. Set as enabled by default. - Linux: `X11` and `Wayland` done. 1. `Wayland` does not allow to listen for keypresses for security reasons. Discussion here: https://github.com/albertlauncher/albert/issues/309 2. For `X11` we can use `XQueryKeymap` to check keyboard state. - Windows: done. We use `GetAsyncKeyState` most significant bit to check if the key is being pressed.
This commit is contained in:
parent
84f3e8ce67
commit
7031c1d155
|
@ -260,6 +260,8 @@ uint32_t throttle = 100;
|
||||||
uint32_t speedup_throttle = 100;
|
uint32_t speedup_throttle = 100;
|
||||||
uint32_t speedup_frame_skip = 9;
|
uint32_t speedup_frame_skip = 9;
|
||||||
bool speedup_throttle_frame_skip = false;
|
bool speedup_throttle_frame_skip = false;
|
||||||
|
bool allowKeyboardBackgroundInput = false;
|
||||||
|
bool allowJoystickBackgroundInput = true;
|
||||||
|
|
||||||
const char* preparedCheatCodes[MAX_CHEATS];
|
const char* preparedCheatCodes[MAX_CHEATS];
|
||||||
|
|
||||||
|
@ -477,6 +479,8 @@ void ValidateConfig()
|
||||||
void LoadConfig()
|
void LoadConfig()
|
||||||
{
|
{
|
||||||
agbPrint = ReadPrefHex("agbPrint");
|
agbPrint = ReadPrefHex("agbPrint");
|
||||||
|
allowKeyboardBackgroundInput = ReadPref("allowKeyboardBackgroundInput", false);
|
||||||
|
allowJoystickBackgroundInput = ReadPref("allowJoystickBackgroundInput", true);
|
||||||
autoFireMaxCount = fromDec(ReadPrefString("autoFireMaxCount"));
|
autoFireMaxCount = fromDec(ReadPrefString("autoFireMaxCount"));
|
||||||
autoFrameSkip = ReadPref("autoFrameSkip", 0);
|
autoFrameSkip = ReadPref("autoFrameSkip", 0);
|
||||||
autoLoadMostRecent = ReadPref("autoLoadMostRecent", 0);
|
autoLoadMostRecent = ReadPref("autoLoadMostRecent", 0);
|
||||||
|
|
|
@ -149,6 +149,8 @@ extern uint32_t throttle;
|
||||||
extern uint32_t speedup_throttle;
|
extern uint32_t speedup_throttle;
|
||||||
extern uint32_t speedup_frame_skip;
|
extern uint32_t speedup_frame_skip;
|
||||||
extern bool speedup_throttle_frame_skip;
|
extern bool speedup_throttle_frame_skip;
|
||||||
|
extern bool allowKeyboardBackgroundInput;
|
||||||
|
extern bool allowJoystickBackgroundInput;
|
||||||
|
|
||||||
extern int preparedCheats;
|
extern int preparedCheats;
|
||||||
extern const char *preparedCheatCodes[MAX_CHEATS];
|
extern const char *preparedCheatCodes[MAX_CHEATS];
|
||||||
|
|
|
@ -718,6 +718,7 @@ add_custom_command(
|
||||||
set(
|
set(
|
||||||
SRC_WX
|
SRC_WX
|
||||||
wxvbam.cpp
|
wxvbam.cpp
|
||||||
|
background-input.cpp
|
||||||
guiinit.cpp
|
guiinit.cpp
|
||||||
viewers.cpp
|
viewers.cpp
|
||||||
gfxviewers.cpp
|
gfxviewers.cpp
|
||||||
|
@ -751,6 +752,7 @@ endif()
|
||||||
set(
|
set(
|
||||||
HDR_WX
|
HDR_WX
|
||||||
wxvbam.h
|
wxvbam.h
|
||||||
|
background-input.h
|
||||||
wxlogdebug.h
|
wxlogdebug.h
|
||||||
drawing.h
|
drawing.h
|
||||||
filters.h
|
filters.h
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef BACKGROUND_INPUT_H
|
||||||
|
#define BACKGROUND_INPUT_H
|
||||||
|
|
||||||
|
#include <wx/event.h>
|
||||||
|
#include <wx/log.h>
|
||||||
|
#include <wx/thread.h>
|
||||||
|
#include <wx/utils.h>
|
||||||
|
#include <wx/window.h>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#if defined(__WXMSW__)
|
||||||
|
extern std::unordered_map<int, wxKeyCode> gs_specialKeys;
|
||||||
|
#elif defined(__WXMAC__)
|
||||||
|
#else // defined(__WXGTK__)
|
||||||
|
extern std::unordered_map<unsigned, int> x11KeySym;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void enableKeyboardBackgroundInput(wxEvtHandler* handler);
|
||||||
|
|
||||||
|
void disableKeyboardBackgroundInput();
|
||||||
|
|
||||||
|
#endif // BACKGROUND_INPUT_H
|
|
@ -1565,6 +1565,36 @@ EVT_HANDLER(JoypadAutoholdStart, "Autohold Start (toggle)")
|
||||||
GetMenuOptionInt(keyName, autohold, keym);
|
GetMenuOptionInt(keyName, autohold, keym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "background-input.h"
|
||||||
|
|
||||||
|
EVT_HANDLER(AllowKeyboardBackgroundInput, "Allow keyboard background input (toggle)")
|
||||||
|
{
|
||||||
|
bool menuPress;
|
||||||
|
GetMenuOptionBool("AllowKeyboardBackgroundInput", menuPress);
|
||||||
|
toggleBooleanVar(&menuPress, &allowKeyboardBackgroundInput);
|
||||||
|
SetMenuOption("AllowKeyboardBackgroundInput", allowKeyboardBackgroundInput ? 1 : 0);
|
||||||
|
|
||||||
|
disableKeyboardBackgroundInput();
|
||||||
|
|
||||||
|
if (allowKeyboardBackgroundInput) {
|
||||||
|
if (panel && panel->panel) {
|
||||||
|
enableKeyboardBackgroundInput(panel->panel->GetWindow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_opts();
|
||||||
|
}
|
||||||
|
|
||||||
|
EVT_HANDLER(AllowJoystickBackgroundInput, "Allow joystick background input (toggle)")
|
||||||
|
{
|
||||||
|
bool menuPress;
|
||||||
|
GetMenuOptionBool("AllowJoystickBackgroundInput", menuPress);
|
||||||
|
toggleBooleanVar(&menuPress, &allowJoystickBackgroundInput);
|
||||||
|
SetMenuOption("AllowJoystickBackgroundInput", allowJoystickBackgroundInput ? 1 : 0);
|
||||||
|
|
||||||
|
update_opts();
|
||||||
|
}
|
||||||
|
|
||||||
EVT_HANDLER_MASK(LoadGameRecent, "Load most recent save", CMDEN_SAVST)
|
EVT_HANDLER_MASK(LoadGameRecent, "Load most recent save", CMDEN_SAVST)
|
||||||
{
|
{
|
||||||
panel->LoadState();
|
panel->LoadState();
|
||||||
|
@ -2611,7 +2641,7 @@ EVT_HANDLER_MASK(DisplayConfigure, "Display options...", CMDEN_NREC_ANY)
|
||||||
|
|
||||||
if (panel->panel) {
|
if (panel->panel) {
|
||||||
panel->panel->Destroy();
|
panel->panel->Destroy();
|
||||||
panel->panel = NULL;
|
panel->panel = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_opts();
|
update_opts();
|
||||||
|
@ -2629,7 +2659,7 @@ EVT_HANDLER_MASK(ChangeFilter, "Change Pixel Filter", CMDEN_NREC_ANY)
|
||||||
|
|
||||||
if (panel->panel) {
|
if (panel->panel) {
|
||||||
panel->panel->Destroy();
|
panel->panel->Destroy();
|
||||||
panel->panel = NULL;
|
panel->panel = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
@ -2644,7 +2674,7 @@ EVT_HANDLER_MASK(ChangeIFB, "Change Interframe Blending", CMDEN_NREC_ANY)
|
||||||
|
|
||||||
if (panel->panel) {
|
if (panel->panel) {
|
||||||
panel->panel->Destroy();
|
panel->panel->Destroy();
|
||||||
panel->panel = NULL;
|
panel->panel = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
#include "../common/ConfigManager.h"
|
#include "../common/ConfigManager.h"
|
||||||
#include "../gba/CheatSearch.h"
|
#include "../gba/CheatSearch.h"
|
||||||
|
|
||||||
|
#if defined(__WXGTK__)
|
||||||
|
#include "wayland.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// The program icon, in case it's missing from .xrc (MSW gets it from .rc file)
|
// The program icon, in case it's missing from .xrc (MSW gets it from .rc file)
|
||||||
#if !defined(__WXMSW__) && !defined(__WXPM__)
|
#if !defined(__WXMSW__) && !defined(__WXPM__)
|
||||||
// ImageMagick makes the name wxvbam, but wx expects wxvbam_xpm
|
// ImageMagick makes the name wxvbam, but wx expects wxvbam_xpm
|
||||||
|
@ -2834,6 +2838,22 @@ bool MainFrame::BindControls()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if defined(__WXMAC__) || defined(__WXGTK__)
|
||||||
|
|
||||||
|
if (cmdtab[i].cmd_id == XRCID("AllowKeyboardBackgroundInput")
|
||||||
|
#if defined(__WXGTK__)
|
||||||
|
&& IsItWayland()
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
if (mi)
|
||||||
|
mi->GetMenu()->Remove(mi);
|
||||||
|
|
||||||
|
cmdtab[i].cmd_id = XRCID("NOOP");
|
||||||
|
cmdtab[i].mi = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef NO_LINK
|
#ifdef NO_LINK
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,8 @@ opt_desc opts[] = {
|
||||||
INTOPT("geometry/windowY", "Y", wxTRANSLATE("Window axis Y position at startup"), windowPositionY, -1, 99999),
|
INTOPT("geometry/windowY", "Y", wxTRANSLATE("Window axis Y position at startup"), windowPositionY, -1, 99999),
|
||||||
|
|
||||||
/// UI
|
/// UI
|
||||||
|
BOOLOPT("ui/allowKeyboardBackgroundInput", "AllowKeyboardBackgroundInput", wxTRANSLATE("Capture key events while on background"), allowKeyboardBackgroundInput),
|
||||||
|
BOOLOPT("ui/allowJoystickBackgroundInput", "AllowJoystickBackgroundInput", wxTRANSLATE("Capture joy events while on background"), allowJoystickBackgroundInput),
|
||||||
BOOLOPT("ui/hideMenuBar", "", wxTRANSLATE("Hide menu bar when mouse is inactive"), gopts.hide_menu_bar),
|
BOOLOPT("ui/hideMenuBar", "", wxTRANSLATE("Hide menu bar when mouse is inactive"), gopts.hide_menu_bar),
|
||||||
|
|
||||||
/// Sound
|
/// Sound
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "wxvbam.h"
|
#include "wxvbam.h"
|
||||||
#include "wxutil.h"
|
#include "wxutil.h"
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
|
#include "background-input.h"
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -328,7 +329,6 @@ void GameArea::LoadGame(const wxString& name)
|
||||||
emulating = true;
|
emulating = true;
|
||||||
was_paused = true;
|
was_paused = true;
|
||||||
MainFrame* mf = wxGetApp().frame;
|
MainFrame* mf = wxGetApp().frame;
|
||||||
mf->StopJoyPollTimer();
|
|
||||||
mf->SetJoystick();
|
mf->SetJoystick();
|
||||||
mf->cmd_enable &= ~(CMDEN_GB | CMDEN_GBA);
|
mf->cmd_enable &= ~(CMDEN_GB | CMDEN_GBA);
|
||||||
mf->cmd_enable |= ONLOAD_CMDEN;
|
mf->cmd_enable |= ONLOAD_CMDEN;
|
||||||
|
@ -557,15 +557,17 @@ void GameArea::UnloadGame(bool destruct)
|
||||||
emusys = NULL;
|
emusys = NULL;
|
||||||
soundShutdown();
|
soundShutdown();
|
||||||
|
|
||||||
|
disableKeyboardBackgroundInput();
|
||||||
|
|
||||||
if (destruct)
|
if (destruct)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// in destructor, panel should be auto-deleted by wx since all panels
|
// in destructor, panel should be auto-deleted by wx since all panels
|
||||||
// are derived from a window attached as child to GameArea
|
// are derived from a window attached as child to GameArea
|
||||||
if (panel)
|
if (panel) {
|
||||||
panel->Destroy();
|
panel->Destroy();
|
||||||
|
panel = nullptr;
|
||||||
panel = NULL;
|
}
|
||||||
|
|
||||||
// close any game-related viewer windows
|
// close any game-related viewer windows
|
||||||
// in destructor, viewer windows are in process of being deleted anyway
|
// in destructor, viewer windows are in process of being deleted anyway
|
||||||
|
@ -579,7 +581,6 @@ void GameArea::UnloadGame(bool destruct)
|
||||||
mf->enable_menus();
|
mf->enable_menus();
|
||||||
mf->SetJoystick();
|
mf->SetJoystick();
|
||||||
mf->ResetCheatSearch();
|
mf->ResetCheatSearch();
|
||||||
mf->StartJoyPollTimer();
|
|
||||||
|
|
||||||
if (rewind_mem)
|
if (rewind_mem)
|
||||||
num_rewind_states = 0;
|
num_rewind_states = 0;
|
||||||
|
@ -702,10 +703,10 @@ void GameArea::AddBorder()
|
||||||
wxGetApp().frame->Fit();
|
wxGetApp().frame->Fit();
|
||||||
GetSizer()->Detach(panel->GetWindow());
|
GetSizer()->Detach(panel->GetWindow());
|
||||||
|
|
||||||
if (panel)
|
if (panel) {
|
||||||
panel->Destroy();
|
panel->Destroy();
|
||||||
|
panel = nullptr;
|
||||||
panel = NULL;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameArea::DelBorder()
|
void GameArea::DelBorder()
|
||||||
|
@ -721,10 +722,10 @@ void GameArea::DelBorder()
|
||||||
wxGetApp().frame->Fit();
|
wxGetApp().frame->Fit();
|
||||||
GetSizer()->Detach(panel->GetWindow());
|
GetSizer()->Detach(panel->GetWindow());
|
||||||
|
|
||||||
if (panel)
|
if (panel) {
|
||||||
panel->Destroy();
|
panel->Destroy();
|
||||||
|
panel = nullptr;
|
||||||
panel = NULL;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameArea::AdjustMinSize()
|
void GameArea::AdjustMinSize()
|
||||||
|
@ -802,7 +803,7 @@ void GameArea::ShowFullScreen(bool full)
|
||||||
// delete panel to be recreated immediately after resize
|
// delete panel to be recreated immediately after resize
|
||||||
if (panel) {
|
if (panel) {
|
||||||
panel->Destroy();
|
panel->Destroy();
|
||||||
panel = NULL;
|
panel = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows does not restore old window size/pos
|
// Windows does not restore old window size/pos
|
||||||
|
@ -1067,6 +1068,10 @@ void GameArea::OnIdle(wxIdleEvent& event)
|
||||||
w->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
w->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
|
||||||
w->SetSize(wxSize(basic_width, basic_height));
|
w->SetSize(wxSize(basic_width, basic_height));
|
||||||
|
|
||||||
|
// Allow input while on background
|
||||||
|
if (allowKeyboardBackgroundInput)
|
||||||
|
enableKeyboardBackgroundInput(w);
|
||||||
|
|
||||||
if (maxScale)
|
if (maxScale)
|
||||||
w->SetMaxSize(wxSize(basic_width * maxScale,
|
w->SetMaxSize(wxSize(basic_width * maxScale,
|
||||||
basic_height * maxScale));
|
basic_height * maxScale));
|
||||||
|
@ -2060,6 +2065,8 @@ DrawingPanelBase::~DrawingPanelBase()
|
||||||
|
|
||||||
delete[] threads;
|
delete[] threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disableKeyboardBackgroundInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicDrawingPanel::BasicDrawingPanel(wxWindow* parent, int _width, int _height)
|
BasicDrawingPanel::BasicDrawingPanel(wxWindow* parent, int _width, int _height)
|
||||||
|
|
|
@ -45,8 +45,10 @@ void wxSDLJoy::CreateAndSendEvent(wxEvtHandler* handler, unsigned short joy, uns
|
||||||
{
|
{
|
||||||
if (!handler) {
|
if (!handler) {
|
||||||
GameArea *panel = wxGetApp().frame->GetPanel();
|
GameArea *panel = wxGetApp().frame->GetPanel();
|
||||||
if (panel) handler = panel->GetEventHandler();
|
if (panel && allowJoystickBackgroundInput)
|
||||||
else return;
|
handler = panel->GetEventHandler();
|
||||||
|
else
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxSDLJoyEvent *ev = new wxSDLJoyEvent(wxEVT_SDLJOY);
|
wxSDLJoyEvent *ev = new wxSDLJoyEvent(wxEVT_SDLJOY);
|
||||||
|
|
|
@ -426,6 +426,14 @@
|
||||||
<object class="wxMenuItem" name="JoypadConfigure">
|
<object class="wxMenuItem" name="JoypadConfigure">
|
||||||
<label>_Configure ...</label>
|
<label>_Configure ...</label>
|
||||||
</object>
|
</object>
|
||||||
|
<object class="wxMenuItem" name="AllowKeyboardBackgroundInput">
|
||||||
|
<label>Allow _keyboard background input</label>
|
||||||
|
<checkable>1</checkable>
|
||||||
|
</object>
|
||||||
|
<object class="wxMenuItem" name="AllowJoystickBackgroundInput">
|
||||||
|
<label>Allow _joystick background input</label>
|
||||||
|
<checkable>1</checkable>
|
||||||
|
</object>
|
||||||
<object class="separator"/>
|
<object class="separator"/>
|
||||||
<object class="wxMenu">
|
<object class="wxMenu">
|
||||||
<label>_Autofire</label>
|
<label>_Autofire</label>
|
||||||
|
|
Loading…
Reference in New Issue