Updated patch - quite a few changes. First I noticed I was inadvertently trapping some keys I shouldn't (try using Ctrl+S with the original patch...), and then I decided to tackle the old "bug" that certain key combinations, like Shift+Tab, cannot be used.
To make sure hotkeys are recognized equally everywhere, I took the code I originally wrote for the hotkey editor widget to handle wxEVT_CHAR and wxEVT_CHAR_HOOK keypress events "intelligently" and factored it out into a separate class to be used in other places. I then pulled it into EDA_DRAW_PANEL and EDA_DRAW_PANEL_GAL to replace the existing keycode rewriting code (which originally was just "if hotkey is in WXK_CONTROL_A through WXK_CONTROL_Z, remap to Ctrl + A..Z"). With this patch, all 'standard' combinations of keys on a US keyboard should be usable, support for international keys is the same as before. Let me know if you find any combinations that don't work. Please test! This is platform-dependent stuff - it's the same platform-dependent stuff as before, but I need to make sure I haven't added regressions. I've tested on Linux and Win10; more thorough testing even on those same platforms is welcome. On Wed, Jan 20, 2016 at 10:44:36PM -0500, Chris Pavlina wrote: > There is an old bug that people turned up while testing my new hotkey > editor, attached is a patch that fixes it. This patch pokes into the > main hotkey handling code, so I really want as many people to test it as > possible - it's a relatively minor bug, I don't want to go introducing > twelve regressions to fix one small bug. Here's what I want to keep an > eye out for: > > - Hotkeys (Ctrl+Tab), (Tab), and (Ctrl+I) are all independent and > distinguished from each other, both in the hotkey editor and in actual > use. Make sure all of them work, and make sure none of them answers > for the others. > > - Hotkeys that are *not* handled by the main hotkey code (for example, > menu keys like Alt+F to call up the File menu) are not affected. > > - Behavior on OSX, with its weird Ctrl mapping, is not broken (or, at > least, is no more broken than usual ;) > > I have tested on Linux and Windows 10, though more thorough testing on > those platforms is welcome. > > Patch/bug summary: > > [PATCH] Fix (Ctrl)+(ASCII control key) hotkey handling > > wxWidgets has quirks with how it handles these keys. For example, in > wxEVT_CHAR, Ctrl+Tab and Ctrl+I are indistinguishable. > > - Modify the special wxEVT_CHAR_HOOK handler from WIDGET_HOTKEY_LIST to > handle this case as well as the other funny cases it already handles. > > - Factor this handler out into a function in hotkeys_basic.h for use > elsewhere. > > - Add this handler to the central hotkey handler, remove existing > (buggy) ASCII control key handling. > > Thanks for testing. > > -- Chris
diff --git a/common/draw_panel.cpp b/common/draw_panel.cpp index 063c5db..5418f4c 100644 --- a/common/draw_panel.cpp +++ b/common/draw_panel.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.char...@gipsa-lab.inpg.fr * Copyright (C) 2007-2011 Wayne Stambaugh <stambau...@verizon.net> - * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -77,7 +77,7 @@ BEGIN_EVENT_TABLE( EDA_DRAW_PANEL, wxScrolledWindow ) #endif EVT_MOUSE_EVENTS( EDA_DRAW_PANEL::OnMouseEvent ) EVT_CHAR( EDA_DRAW_PANEL::OnKeyEvent ) - EVT_CHAR_HOOK( EDA_DRAW_PANEL::OnCharHook ) + EVT_CHAR_HOOK( EDA_DRAW_PANEL::OnKeyEvent ) EVT_PAINT( EDA_DRAW_PANEL::OnPaint ) EVT_ERASE_BACKGROUND( EDA_DRAW_PANEL::OnEraseBackground ) EVT_SCROLLWIN( EDA_DRAW_PANEL::OnScroll ) @@ -1381,59 +1381,27 @@ void EDA_DRAW_PANEL::OnMouseEvent( wxMouseEvent& event ) } - -void EDA_DRAW_PANEL::OnCharHook( wxKeyEvent& event ) -{ - event.Skip(); -} - void EDA_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event ) { - int localkey; - wxPoint pos; + if( !m_hkfilter.should_process( event ) ) + { + return; + } - localkey = event.GetKeyCode(); + wxPoint pos; + EDA_KEY key = MapKeypressToKeycode( event ); - switch( localkey ) + if( key == GR_KEY_NONE ) { - default: - break; - - case WXK_ESCAPE: + // escape key m_abortRequest = true; if( IsMouseCaptured() ) EndMouseCapture(); else EndMouseCapture( ID_NO_TOOL_SELECTED, m_defaultCursor, wxEmptyString ); - break; } - /* Normalize keys code to easily handle keys from Ctrl+A to Ctrl+Z - * They have an ascii code from 1 to 27 remapped - * to GR_KB_CTRL + 'A' to GR_KB_CTRL + 'Z' - */ - if( event.ControlDown() && localkey >= WXK_CONTROL_A && localkey <= WXK_CONTROL_Z ) - localkey += 'A' - 1; - - /* Disallow shift for keys that have two keycodes on them (e.g. number and - * punctuation keys) leaving only the "letter keys" of A-Z. - * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout) - * and Ctrl-( and Ctrl-5 (FR layout). - * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout - */ - bool keyIsLetter = ( localkey >= 'A' && localkey <= 'Z' ) || - ( localkey >= 'a' && localkey <= 'z' ); - - if( event.ShiftDown() && ( keyIsLetter || localkey > 256 ) ) - localkey |= GR_KB_SHIFT; - - if( event.ControlDown() ) - localkey |= GR_KB_CTRL; - - if( event.AltDown() ) - localkey |= GR_KB_ALT; - INSTALL_UNBUFFERED_DC( DC, this ); // Some key commands use the current mouse position: refresh it. @@ -1444,8 +1412,10 @@ void EDA_DRAW_PANEL::OnKeyEvent( wxKeyEvent& event ) GetParent()->SetMousePosition( pos ); - if( !GetParent()->GeneralControl( &DC, pos, localkey ) ) - event.Skip(); + if( !GetParent()->GeneralControl( &DC, pos, key ) ) + { + m_hkfilter.skip( event ); + } } diff --git a/common/draw_panel_gal.cpp b/common/draw_panel_gal.cpp index c060ab5..50bd478 100644 --- a/common/draw_panel_gal.cpp +++ b/common/draw_panel_gal.cpp @@ -82,7 +82,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin wxEVT_LEFT_UP, wxEVT_LEFT_DOWN, wxEVT_LEFT_DCLICK, wxEVT_RIGHT_UP, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_DCLICK, wxEVT_MIDDLE_UP, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_DCLICK, - wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, + wxEVT_MOTION, wxEVT_MOUSEWHEEL, wxEVT_CHAR, wxEVT_CHAR_HOOK, #ifdef USE_OSX_MAGNIFY_EVENT wxEVT_MAGNIFY, #endif diff --git a/common/hotkeys_basic.cpp b/common/hotkeys_basic.cpp index 04dfd7f..171933c 100644 --- a/common/hotkeys_basic.cpp +++ b/common/hotkeys_basic.cpp @@ -509,7 +509,7 @@ void DisplayHotkeyList( EDA_BASE_FRAME* aFrame, struct EDA_HOTKEY_CONFIG* aDescL * @param aList = pointer to a EDA_HOTKEY list of commands * @return the corresponding EDA_HOTKEY pointer from the EDA_HOTKEY List */ -EDA_HOTKEY* GetDescriptorFromHotkey( int aKey, EDA_HOTKEY** aList ) +EDA_HOTKEY* GetDescriptorFromHotkey( EDA_KEY aKey, EDA_HOTKEY** aList ) { for( ; *aList != NULL; aList++ ) { @@ -844,3 +844,142 @@ void AddHotkeyConfigMenu( wxMenu* aMenu ) _( "Hotkeys configuration and preferences" ), KiBitmap( hotkeys_xpm ) ); } + + +EDA_HOTKEY_HOOK_FILTER::EDA_HOTKEY_HOOK_FILTER() +{ + m_skip_evtchar = false; +} + + +bool EDA_HOTKEY_HOOK_FILTER::should_process_in_hook( wxKeyEvent& aEvent ) +{ + // On certain platforms, EVT_CHAR_HOOK is the only handler that receives + // certain "special" keys. However, it doesn't always receive "normal" + // keys correctly. For example, with a US keyboard, it sees ? as shift+/. + // + // Untangling these incorrect keys would be too much trouble, so we bind + // both events, and simply skip the EVT_CHAR_HOOK if it receives a + // "normal" key. + + 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 < DIM( skipped_keys ); ++i ) + { + if( key == skipped_keys[i] ) + return false; + } + + // Some control keys map to Ctrl+letter (e.g. Tab is Ctrl+I) in OnChar, + // but not OnCharHook. This leads to incorrect recognition of + // Ctrl+controlkey (e.g. Ctrl+Tab is seen as just Ctrl+I). Detect + // this and handle here instead. + + bool ctrl_alphakey = ( ( key >= 'A' && key <= 'Z' ) || ( key >= 'a' && key <= 'z' ) ) + && aEvent.ControlDown(); + + bool ctrl_ctrlkey = ( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z ) + && aEvent.ControlDown(); + + return !( key <= 255 && isprint( key ) && !isspace( key ) && !ctrl_ctrlkey && !ctrl_alphakey ); +} + + +void EDA_HOTKEY_HOOK_FILTER::allow_char_hook_propagation( wxKeyEvent& aEvent ) +{ + // Let EVT_CHAR handle this one + aEvent.DoAllowNextEvent(); + + skip( aEvent ); +} + + +bool EDA_HOTKEY_HOOK_FILTER::should_process( wxKeyEvent& aEvent ) +{ + if( aEvent.GetEventType() == wxEVT_CHAR_HOOK ) + { + m_skip_evtchar = should_process_in_hook( aEvent ); + + // Windows quirk: do NOT let the \t wxEVT_CHAR_HOOK produce + // wxEVT_CHAR. In some dialogs (particularly empty ones, see + // the dialog used for hotkey detection in WIDGET_HOTKEY_LIST), + // this will cause the application to freeze. + if( aEvent.GetKeyCode() != '\t' ) + allow_char_hook_propagation( aEvent ); + return m_skip_evtchar; + } + else + { + wxASSERT( aEvent.GetEventType() == wxEVT_CHAR ); + if( !m_skip_evtchar ) + { + return true; + } + else + { + aEvent.Skip(); + return false; + } + } +} + + +void EDA_HOTKEY_HOOK_FILTER::skip( wxKeyEvent& aEvent ) +{ + if( aEvent.GetEventType() == wxEVT_CHAR_HOOK ) + { + // On Windows, wxEvent::Skip must NOT be called. + // On Linux and OSX, wxEvent::Skip MUST be called. + // No, I don't know why. +#ifndef __WXMSW__ + aEvent.Skip(); +#endif + } + else + { + aEvent.Skip(); + } + +} + + +EDA_KEY MapKeypressToKeycode( const wxKeyEvent& aEvent ) +{ + EDA_KEY key = ( EDA_KEY ) aEvent.GetKeyCode(); + + if( key == WXK_ESCAPE ) + { + return GR_KEY_NONE; + } + else + { + if( key >= 'a' && key <= 'z' ) // convert to uppercase + key = key + ('A' - 'a'); + + /* Disallow shift for keys that have two keycodes on them (e.g. number and + * punctuation keys) leaving only the "letter keys" of A-Z. + * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout) + * and Ctrl-( and Ctrl-5 (FR layout). + * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout + */ + bool keyIsLetter = key >= 'A' && key <= 'Z'; + bool keyIsControl = key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z; + + if( aEvent.ShiftDown() && ( keyIsLetter || keyIsControl || key > 256 ) ) + key |= GR_KB_SHIFT; + + if( aEvent.ControlDown() ) + key |= GR_KB_CTRL; + + if( aEvent.AltDown() ) + key |= GR_KB_ALT; + + return key; + } +} diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp index 97127ce..99c6a28 100644 --- a/common/tool/tool_dispatcher.cpp +++ b/common/tool/tool_dispatcher.cpp @@ -2,6 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors. * @author Tomasz Wlostowski <tomasz.wlostow...@cern.ch> * * This program is free software; you can redistribute it and/or @@ -291,32 +292,20 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent ) } // Keyboard handling - else if( type == wxEVT_CHAR ) + else if( type == wxEVT_CHAR || type == wxEVT_CHAR_HOOK ) { wxKeyEvent* ke = static_cast<wxKeyEvent*>( &aEvent ); - int key = ke->GetKeyCode(); - int mods = decodeModifiers( ke ); - if( mods & MD_CTRL ) + if( m_hkfilter.should_process( *ke ) ) { -#if !wxCHECK_VERSION( 2, 9, 0 ) - // I really look forward to the day when we will use only one version of wxWidgets.. - const int WXK_CONTROL_A = 1; - const int WXK_CONTROL_Z = 26; -#endif + int key = ke->GetKeyCode(); + int mods = decodeModifiers( ke ); - // wxWidgets have a quirk related to Ctrl+letter hot keys handled by CHAR_EVT - // http://docs.wxwidgets.org/trunk/classwx_key_event.html: - // "char events for ASCII letters in this case carry codes corresponding to the ASCII - // value of Ctrl-Latter, i.e. 1 for Ctrl-A, 2 for Ctrl-B and so on until 26 for Ctrl-Z." - if( key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z ) - key += 'A' - 1; + if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools + evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ); + else + evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_PRESSED, key | mods ); } - - if( key == WXK_ESCAPE ) // ESC is the special key for cancelling tools - evt = TOOL_EVENT( TC_COMMAND, TA_CANCEL_TOOL ); - else - evt = TOOL_EVENT( TC_KEYBOARD, TA_KEY_PRESSED, key | mods ); } if( evt ) diff --git a/common/widgets/widget_hotkey_list.cpp b/common/widgets/widget_hotkey_list.cpp index 3813670..ecc3e4b 100644 --- a/common/widgets/widget_hotkey_list.cpp +++ b/common/widgets/widget_hotkey_list.cpp @@ -84,6 +84,7 @@ public: class HK_PROMPT_DIALOG : public DIALOG_SHIM { wxKeyEvent m_event; + EDA_HOTKEY_HOOK_FILTER m_hkfilter; public: HK_PROMPT_DIALOG( wxWindow* aParent, wxWindowID aId, const wxString& aTitle, @@ -145,61 +146,21 @@ public: // Binding both EVT_CHAR and EVT_CHAR_HOOK ensures that all key events, // including specials like Tab and Return, are received, particularly // on MSW. - panel->Bind( wxEVT_CHAR, &HK_PROMPT_DIALOG::OnChar, this ); - panel->Bind( wxEVT_CHAR_HOOK, &HK_PROMPT_DIALOG::OnCharHook, this ); + panel->Bind( wxEVT_CHAR, &HK_PROMPT_DIALOG::OnKeyEvent, this ); + panel->Bind( wxEVT_CHAR_HOOK, &HK_PROMPT_DIALOG::OnKeyEvent, this ); } - void OnCharHook( wxKeyEvent& aEvent ) + void OnKeyEvent( wxKeyEvent& aEvent ) { - // On certain platforms, EVT_CHAR_HOOK is the only handler that receives - // certain "special" keys. However, it doesn't always receive "normal" - // keys correctly. For example, with a US keyboard, it sees ? as shift+/. - // - // Untangling these incorrect keys would be too much trouble, so we bind - // both events, and simply skip the EVT_CHAR_HOOK if it receives a - // "normal" key. - - const enum wxKeyCode skipped_keys[] = + if( m_hkfilter.should_process( aEvent ) ) { - 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 ) - { - if( key == skipped_keys[i] ) - return; - } - - if( key <= 255 && isprint( key ) && !isspace( key ) ) - { - // Let EVT_CHAR handle this one - aEvent.DoAllowNextEvent(); - - // On Windows, wxEvent::Skip must NOT be called. - // On Linux and OSX, wxEvent::Skip MUST be called. - // No, I don't know why. -#ifndef __WXMSW__ - aEvent.Skip(); -#endif - } - else - { - OnChar( aEvent ); + m_event = aEvent; + EndFlexible( wxID_OK ); } } - void OnChar( wxKeyEvent& aEvent ) - { - m_event = aEvent; - EndFlexible( wxID_OK ); - } - - /** * End the dialog whether modal or quasimodal */ @@ -302,7 +263,7 @@ void WIDGET_HOTKEY_LIST::EditItem( wxTreeListItem aItem ) wxString current_key = GetItemText( aItem, 1 ); wxKeyEvent key_event = HK_PROMPT_DIALOG::PromptForKey( GetParent(), name, current_key ); - long key = MapKeypressToKeycode( key_event ); + EDA_KEY key = MapKeypressToKeycode( key_event ); if( hkdata && key ) { @@ -438,7 +399,7 @@ void WIDGET_HOTKEY_LIST::OnSize( wxSizeEvent& aEvent ) } -bool WIDGET_HOTKEY_LIST::CheckKeyConflicts( long aKey, const wxString& aSectionTag, +bool WIDGET_HOTKEY_LIST::CheckKeyConflicts( EDA_KEY aKey, const wxString& aSectionTag, EDA_HOTKEY** aConfKey, EDA_HOTKEY_CONFIG** aConfSect ) { EDA_HOTKEY* conflicting_key = NULL; @@ -632,43 +593,3 @@ bool WIDGET_HOTKEY_LIST::TransferDataFromControl() return true; } - - -long WIDGET_HOTKEY_LIST::MapKeypressToKeycode( const wxKeyEvent& aEvent ) -{ - long key = aEvent.GetKeyCode(); - - if( key == WXK_ESCAPE ) - { - return 0; - } - else - { - if( key >= 'a' && key <= 'z' ) // convert to uppercase - key = key + ('A' - 'a'); - - // Remap Ctrl A (=1+GR_KB_CTRL) to Ctrl Z(=26+GR_KB_CTRL) - // to GR_KB_CTRL+'A' .. GR_KB_CTRL+'Z' - if( aEvent.ControlDown() && key >= WXK_CONTROL_A && key <= WXK_CONTROL_Z ) - key += 'A' - 1; - - /* Disallow shift for keys that have two keycodes on them (e.g. number and - * punctuation keys) leaving only the "letter keys" of A-Z. - * Then, you can have, e.g. Ctrl-5 and Ctrl-% (GB layout) - * and Ctrl-( and Ctrl-5 (FR layout). - * Otherwise, you'd have to have to say Ctrl-Shift-5 on a FR layout - */ - bool keyIsLetter = key >= 'A' && key <= 'Z'; - - if( aEvent.ShiftDown() && ( keyIsLetter || key > 256 ) ) - key |= GR_KB_SHIFT; - - if( aEvent.ControlDown() ) - key |= GR_KB_CTRL; - - if( aEvent.AltDown() ) - key |= GR_KB_ALT; - - return key; - } -} diff --git a/include/class_drawpanel.h b/include/class_drawpanel.h index 8c386f0..571346b 100644 --- a/include/class_drawpanel.h +++ b/include/class_drawpanel.h @@ -3,7 +3,7 @@ * * Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.char...@gipsa-lab.inpg.com * Copyright (C) 2011 Wayne Stambaugh <stambau...@verizon.net> - * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -34,7 +34,7 @@ #include <colors.h> #include <base_struct.h> #include <gr_basic.h> - +#include <hotkeys_basic.h> class BASE_SCREEN; class PCB_SCREEN; @@ -116,6 +116,9 @@ private: /// >= 0 (or >= n) if a block can start int m_canStartBlock; + /// Hotkey event filter, for handling key events + EDA_HOTKEY_HOOK_FILTER m_hkfilter; + public: EDA_DRAW_PANEL( EDA_DRAW_FRAME* parent, int id, const wxPoint& pos, const wxSize& size ); @@ -270,7 +273,6 @@ public: void OnMouseEntering( wxMouseEvent& aEvent ); void OnMouseLeaving( wxMouseEvent& event ); void OnKeyEvent( wxKeyEvent& event ); - void OnCharHook( wxKeyEvent& event ); void OnPan( wxCommandEvent& event ); diff --git a/include/hotkeys_basic.h b/include/hotkeys_basic.h index 089fcce..abd62ba 100644 --- a/include/hotkeys_basic.h +++ b/include/hotkeys_basic.h @@ -57,7 +57,7 @@ extern wxString g_CommonSectionTag; class EDA_HOTKEY { public: - int m_KeyCode; // Key code (ascii value for ascii keys or wxWidgets code for function key + EDA_KEY m_KeyCode; // Key code (ascii value for ascii keys or wxWidgets code for function key wxString m_InfoMsg; // info message. int m_Idcommand; // internal id for the corresponding command (see hotkey_id_commnand list) int m_IdMenuEvent; // id to call the corresponding event (if any) (see id.h) @@ -203,7 +203,7 @@ void DisplayHotkeyList( EDA_BASE_FRAME* aFrame, struct EDA_HOTKEY_CONFIG* aList * @param aList = pointer to a EDA_HOTKEY list of commands * @return the corresponding EDA_HOTKEY pointer from the EDA_HOTKEY List */ -EDA_HOTKEY* GetDescriptorFromHotkey( int aKey, EDA_HOTKEY** aList ); +EDA_HOTKEY* GetDescriptorFromHotkey( EDA_KEY aKey, EDA_HOTKEY** aList ); /** * Function GetDescriptorFromCommand @@ -244,4 +244,57 @@ enum common_hotkey_id_commnand { HK_COMMON_END }; +/** + * Class EDA_HOTKEY_HOOK_FILTER + * + * Check if a key received by wxEVT_CHAR_HOOK is a "special" key that has to be + * handled at wxEVT_CHAR_HOOK rather than wxEVT_CHAR. This is the case for + * combinations like Ctrl+Tab, which are indistinguishable from Ctrl+I in + * wxEVT_CHAR. Other events must be handled in wxEVT_CHAR instead, as + * wxEVT_CHAR_HOOK handled them before input method filters have been applied. + * An example implementation is: + * + * void OnKeyEvent( wxKeyEvent& aEvent ) // reponds to wxEVT_CHAR and wxEVT_CHAR_HOOK + * { + * static EDA_HOTKEY_HOOK_FILTER filter; + * + * if( !filter.should_process( aEvent ) ) + * { + * return; + * } + * + * ...... + * + * if( something ) + * { + * filter.skip( aEvent ); + * } + * } + * + */ +class EDA_HOTKEY_HOOK_FILTER +{ + bool m_skip_evtchar; + + static bool should_process_in_hook( wxKeyEvent &aEvent ); + + static void allow_char_hook_propagation( wxKeyEvent &aEvent ); + +public: + EDA_HOTKEY_HOOK_FILTER(); + + /** + * Analyze an event and determine whether it should be processed. + */ + bool should_process( wxKeyEvent& aEvent ); + + /** + * Skip event. Use this instead of wxEvent::Skip, as the behavior + * of that for wxEVT_CHAR_HOOK is platform-dependent. + */ + static void skip( wxKeyEvent& aEvent ); +}; + +EDA_KEY MapKeypressToKeycode( const wxKeyEvent& aEvent ); + #endif // HOTKEYS_BASIC_H diff --git a/include/tool/tool_dispatcher.h b/include/tool/tool_dispatcher.h index cf6e852..ff1e0b5 100644 --- a/include/tool/tool_dispatcher.h +++ b/include/tool/tool_dispatcher.h @@ -2,6 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2013 CERN + * Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors. * @author Tomasz Wlostowski <tomasz.wlostow...@cern.ch> * * This program is free software; you can redistribute it and/or @@ -26,6 +27,7 @@ #define __TOOL_DISPATCHER_H #include <vector> +#include <hotkeys_basic.h> #include <wx/event.h> #include <tool/tool_event.h> @@ -130,6 +132,9 @@ private: ///> Instance of tool manager that cooperates with the dispatcher. TOOL_MANAGER* m_toolMgr; + + ///> Hotkey filter instance for handling keypress events + EDA_HOTKEY_HOOK_FILTER m_hkfilter; }; #endif diff --git a/include/widgets/widget_hotkey_list.h b/include/widgets/widget_hotkey_list.h index bfaf010..a29264d 100644 --- a/include/widgets/widget_hotkey_list.h +++ b/include/widgets/widget_hotkey_list.h @@ -130,7 +130,7 @@ protected: * @param aConfKey - if not NULL, outparam getting the key this one conflicts with * @param aConfSect - if not NULL, outparam getting the section this one conflicts with */ - bool CheckKeyConflicts( long aKey, const wxString& aSectionTag, + bool CheckKeyConflicts( EDA_KEY aKey, const wxString& aSectionTag, EDA_HOTKEY** aConfKey, EDA_HOTKEY_CONFIG** aConfSect ); /** @@ -191,12 +191,6 @@ public: * @return true iff the operation was successful */ bool TransferDataFromControl(); - - /** - * Static method MapKeypressToKeycode - * Map a keypress event to the correct key code for use as a hotkey. - */ - static long MapKeypressToKeycode( const wxKeyEvent& aEvent ); }; #endif // __widget_hotkey_list__
_______________________________________________ Mailing list: https://launchpad.net/~kicad-developers Post to : kicad-developers@lists.launchpad.net Unsubscribe : https://launchpad.net/~kicad-developers More help : https://help.launchpad.net/ListHelp