fix modifier-only game keys
Fix using modifier keys such as SHIFT or CONTROL by themselves as game keys. Modifier keys are sent as a special keycode e.g. WXK_CTRL along with the modifier flag, however on key release the keycode is sent but the modifier flag is not. So check for modifier keys in process_key_press() and always set the modifier flag so that release events are recognized correctly. Fix support for RAW_CTRL on Mac (which is the real control, while the Command key is mapped to CTRL.) Also disable the debug message emitted by wX when our modifier-only key parsing code runs. TODO: map modifier key names on Mac to the actual keys rather than the wX names such as RAWCTRL.
This commit is contained in:
parent
a60d24e91a
commit
8c309eaaf4
|
@ -1119,6 +1119,23 @@ static bool process_key_press(bool down, int key, int mod, int joy = 0)
|
|||
{
|
||||
static bool in_game_key = false;
|
||||
|
||||
// modifier-only key releases do not set the modifier flag
|
||||
// so we set it here to match key release events to key press events
|
||||
switch (key) {
|
||||
case WXK_SHIFT:
|
||||
mod |= wxMOD_SHIFT;
|
||||
break;
|
||||
case WXK_ALT:
|
||||
mod |= wxMOD_ALT;
|
||||
break;
|
||||
case WXK_CONTROL:
|
||||
mod |= wxMOD_CONTROL;
|
||||
break;
|
||||
case WXK_RAW_CONTROL:
|
||||
mod |= wxMOD_RAW_CONTROL;
|
||||
break;
|
||||
}
|
||||
|
||||
// check if key is already pressed
|
||||
int kpno;
|
||||
|
||||
|
@ -1155,6 +1172,7 @@ static bool process_key_press(bool down, int key, int mod, int joy = 0)
|
|||
for (int k = 0; k < b.size(); k++)
|
||||
if (b[k].key == key && b[k].mod == mod && b[k].joy == joy) {
|
||||
if (down) {
|
||||
// press button
|
||||
joypress[i] |= bmask[j];
|
||||
matched_game_key = true;
|
||||
}
|
||||
|
@ -1175,6 +1193,7 @@ static bool process_key_press(bool down, int key, int mod, int joy = 0)
|
|||
}
|
||||
|
||||
if (k2 == b.size()) {
|
||||
// release button
|
||||
joypress[i] &= ~bmask[j];
|
||||
matched_game_key = true;
|
||||
}
|
||||
|
@ -1185,7 +1204,7 @@ static bool process_key_press(bool down, int key, int mod, int joy = 0)
|
|||
}
|
||||
|
||||
in_game_key = matched_game_key;
|
||||
|
||||
|
||||
return in_game_key;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <wx/log.h>
|
||||
#include "wx/keyedit.h"
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxKeyTextCtrl, wxTextCtrl)
|
||||
|
@ -71,7 +72,7 @@ wxString wxKeyTextCtrl::ToString(int mod, int key)
|
|||
// before passing to ToString()
|
||||
bool char_override = key > 32 && key < WXK_START && !wxIsalnum(key);
|
||||
// wx also ignores modifiers (and does not report meta at all)
|
||||
bool mod_override = key == WXK_SHIFT || key == WXK_CONTROL || key == WXK_ALT;
|
||||
bool mod_override = key == WXK_SHIFT || key == WXK_CONTROL || key == WXK_ALT || key == WXK_RAW_CONTROL;
|
||||
wxAcceleratorEntry ae(mod, char_override || mod_override ? WXK_F1 : key);
|
||||
// Note: wx translates unconditionally (2.8.12, 2.9.1)!
|
||||
// So any strings added below must also be translated unconditionally
|
||||
|
@ -120,7 +121,8 @@ wxString wxKeyTextCtrl::ToString(int mod, int key)
|
|||
|
||||
#endif
|
||||
|
||||
if (s.empty() || (key != wxT('-') && s[s.size() - 1] == wxT('-')))
|
||||
if (s.empty() || (key != wxT('-') && s[s.size() - 1] == wxT('-'))
|
||||
|| (key != wxT('+') && s[s.size() - 1] == wxT('+')))
|
||||
// bad key combo; probably also generates an assertion in wx
|
||||
return wxEmptyString;
|
||||
|
||||
|
@ -193,38 +195,39 @@ bool wxKeyTextCtrl::ParseString(const wxChar* s, int len, int& mod, int& key)
|
|||
// unlike ToString(), this generates a debug message rather than
|
||||
// an assertion error, so it's easy to ignore and expensive to avoid
|
||||
// beforehand. Instead, check for them on failure
|
||||
wxLogNull disable_logging;
|
||||
if (!ae.FromString(a)) {
|
||||
a.MakeUpper();
|
||||
#define chk_str(n, k) \
|
||||
#define chk_str(n, k, m) \
|
||||
do { \
|
||||
wxString t = n; \
|
||||
if (a.size() > t.size() && a.substr(a.size() - t.size()) == t) { \
|
||||
a.replace(a.size() - t.size(), t.size(), wxT("F1")); \
|
||||
wxString ss(s); \
|
||||
if (ae.FromString(a)) { \
|
||||
mod |= ae.GetFlags(); \
|
||||
mod |= ae.GetFlags() | m; \
|
||||
key = k; \
|
||||
return true; \
|
||||
} \
|
||||
a.replace(a.size() - 2, 2, n); \
|
||||
} \
|
||||
} while (0)
|
||||
chk_str(wxT("ALT"), WXK_ALT);
|
||||
chk_str(wxT("SHIFT"), WXK_SHIFT);
|
||||
chk_str(wxT("CTRL"), WXK_CONTROL);
|
||||
chk_str(wxT("CONTROL"), WXK_CONTROL);
|
||||
chk_str(wxT("RAWCTRL"), WXK_CONTROL);
|
||||
chk_str(wxT("RAW_CTRL"), WXK_RAW_CONTROL);
|
||||
chk_str(wxT("RAWCONTROL"), WXK_RAW_CONTROL);
|
||||
chk_str(wxT("RAW_CONTROL"), WXK_RAW_CONTROL);
|
||||
chk_str(_("ALT"), WXK_ALT);
|
||||
chk_str(_("SHIFT"), WXK_SHIFT);
|
||||
chk_str(_("CTRL"), WXK_CONTROL);
|
||||
chk_str(_("CONTROL"), WXK_CONTROL);
|
||||
chk_str(_("RAWCTRL"), WXK_RAW_CONTROL);
|
||||
chk_str(_("RAW_CTRL"), WXK_RAW_CONTROL);
|
||||
chk_str(_("RAWCONTROL"), WXK_RAW_CONTROL);
|
||||
chk_str(_("RAW_CONTROL"), WXK_RAW_CONTROL);
|
||||
chk_str(wxT("ALT"), WXK_ALT, wxMOD_ALT);
|
||||
chk_str(wxT("SHIFT"), WXK_SHIFT, wxMOD_SHIFT);
|
||||
chk_str(wxT("RAWCTRL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(wxT("RAW_CTRL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(wxT("RAWCONTROL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(wxT("RAW_CONTROL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(_("ALT"), WXK_ALT, wxMOD_ALT);
|
||||
chk_str(_("SHIFT"), WXK_SHIFT, wxMOD_SHIFT);
|
||||
chk_str(_("RAWCTRL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(_("RAW_CTRL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(_("RAWCONTROL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(_("RAW_CONTROL"), WXK_RAW_CONTROL, wxMOD_RAW_CONTROL);
|
||||
chk_str(wxT("CTRL"), WXK_CONTROL, wxMOD_CONTROL);
|
||||
chk_str(wxT("CONTROL"), WXK_CONTROL, wxMOD_CONTROL);
|
||||
chk_str(_("CTRL"), WXK_CONTROL, wxMOD_CONTROL);
|
||||
chk_str(_("CONTROL"), WXK_CONTROL, wxMOD_CONTROL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue