Clean up EVT_CHAR_HOOK and fix a bug on Linux

Forgot aEvent.Skip()
This commit is contained in:
Chris Pavlina 2016-01-15 21:07:12 -05:00 committed by Chris Pavlina
parent 95988802f7
commit 4391f99a25
1 changed files with 44 additions and 38 deletions

View File

@ -22,6 +22,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <cctype>
#include <widgets/widget_hotkey_list.h> #include <widgets/widget_hotkey_list.h>
#include <wx/dataview.h> #include <wx/dataview.h>
@ -36,6 +38,7 @@
*/ */
static const int HOTKEY_MIN_WIDTH = 100; static const int HOTKEY_MIN_WIDTH = 100;
/** /**
* Extra margin to compensate for vertical scrollbar * Extra margin to compensate for vertical scrollbar
*/ */
@ -137,55 +140,57 @@ public:
SetMinClientSize( GetClientSize() ); SetMinClientSize( GetClientSize() );
// Binding both EVT_CHAR and EVT_CHAR_HOOK to the same handler ensures that // Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events,
// all key events, including specials like Tab and Return, are received, // including specials like Tab and Return, are received, particularly
// particularly on MSW. // on MSW.
panel->Bind( wxEVT_CHAR, &HK_PROMPT_DIALOG::OnChar, this ); panel->Bind( wxEVT_CHAR, &HK_PROMPT_DIALOG::OnChar, this );
panel->Bind( wxEVT_CHAR_HOOK, &HK_PROMPT_DIALOG::OnChar, this ); panel->Bind( wxEVT_CHAR_HOOK, &HK_PROMPT_DIALOG::OnCharHook, this );
} }
void OnChar( wxKeyEvent& aEvent )
{
long key = aEvent.GetKeyCode();
// Some of these keys are duplicates on some platforms, so a switch() void OnCharHook( wxKeyEvent& aEvent )
// won't work. {
if( key == WXK_NONE // On certain platforms, EVT_CHAR_HOOK is the only handler that receives
|| key == WXK_SHIFT // certain "special" keys. However, it doesn't always receive "normal"
|| key == WXK_ALT // keys correctly. For example, with a US keyboard, it sees ? as shift+/.
|| key == WXK_CONTROL //
|| key == WXK_CAPITAL // Untangling these incorrect keys would be too much trouble, so we bind
|| key == WXK_NUMLOCK // both events, and simply skip the EVT_CHAR_HOOK if it receives a
|| key == WXK_SCROLL // "normal" key.
|| key == WXK_RAW_CONTROL
|| key == WXK_COMMAND const enum wxKeyCode skipped_keys[] = {
) WXK_NONE, WXK_SHIFT, WXK_ALT, WXK_CONTROL, WXK_CAPITAL,
WXK_NUMLOCK, WXK_SCROLL, WXK_RAW_CONTROL };
int key = aEvent.GetKeyCode();
for( size_t i = 0; i < sizeof( skipped_keys )/sizeof( skipped_keys[0] ); ++i )
{ {
return; if( key == skipped_keys[i] )
return;
}
if( key <= 255 && isprint( key ) )
{
// Let EVT_CHAR handle this one
aEvent.DoAllowNextEvent();
aEvent.Skip();
} }
else else
{ {
m_event = aEvent; OnChar( aEvent );
// EVT_CHAR_HOOK returns some incorrect keys (shift+symbol,
// in particular). If the key is an ASCII printable, grab the
// code from GetUnicodeKey instead.
// TODO: Make the whole hotkey system support Unicode keys.
if( aEvent.GetKeyCode() >= '!' && aEvent.GetKeyCode() <= '~' )
{
if( aEvent.GetEventType() == wxEVT_CHAR_HOOK )
{
aEvent.DoAllowNextEvent();
return;
}
}
EndFlexible( wxID_OK );
} }
} }
void OnChar( wxKeyEvent& aEvent )
{
m_event = aEvent;
EndFlexible( wxID_OK );
}
/** /**
* End the dialog whether modal or quasimodal * End the dialog whether modal or quasimodal
*/ */
@ -197,6 +202,7 @@ public:
EndModal( aRtnCode ); EndModal( aRtnCode );
} }
static wxKeyEvent PromptForKey( wxWindow* aParent, const wxString& aName, static wxKeyEvent PromptForKey( wxWindow* aParent, const wxString& aName,
const wxString& aCurrentKey ) const wxString& aCurrentKey )
{ {