← Back to team overview

kicad-developers team mailing list archive

Re: "Tutorial" on modern toolset events & actions

 

Le 06/07/2019 à 19:43, Jeff Young a écrit :
> OK, not really.  More of an “exercise left to the reader”.
> 
> I'm working through a bug that doesn’t reproduce on OSX, and so have
> been leaning on others (JP so far) to do a bit of sleuthing. One
> side-effect is that there is a lot of info in the bug report for people
> who aren’t familiar with the modern toolset.  Might be worth reading if
> you’re interested and haven’t been following it.
> 
> https://bugs.launchpad.net/kicad/+bug/1835083 ;
> 

Hi Jeff,

Could you test this patch on OSX?
(This patch is for tests only, not for committing)
It fixes the Ctrl+D issue on Windows (but do not change anything on Linux).

On Windows, the root cause was a wxEVT_CHAR_HOOK/wxEVT_CHAR filtering
that filters the Ctrl+D (and certainly some others Ctrl+ ...) char
events, and never dispatch it by the event dispatcher.

The wxEVT_CHAR_HOOK/wxEVT_CHAR event handling is very tricky and is
specific to each platform and what is working on a platform does not
always work on the other platforms.

Even with this patch, the Ctrl+X and the Ctrl+C commands do not work on
Windows in immediate mode.
Are they workinf on OSX?

On Linux, with or without the patch:
- Ctrl+X and the Ctrl+C commands do not work in immediate mode
- Ctrl+D selects the symbol, but does not duplicate it.

-- 
Jean-Pierre CHARRAS
 common/tool/tool_dispatcher.cpp | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/common/tool/tool_dispatcher.cpp b/common/tool/tool_dispatcher.cpp
index f9b93206d..ae792e91d 100644
--- a/common/tool/tool_dispatcher.cpp
+++ b/common/tool/tool_dispatcher.cpp
@@ -247,7 +247,7 @@ bool TOOL_DISPATCHER::handleMouseButton( wxEvent& aEvent, int aIndex, bool aMoti
     return false;
 }
 
-
+#ifdef LEGACY_KEY_HANDLING
 // Helper function to know if a special key ( see key list ) should be captured
 // or if the event can be skipped
 // on Linux, the event must be passed to the GUI if they are not used by KiCad,
@@ -277,9 +277,30 @@ bool isKeySpecialCode( int aKeyCode )
 
     return isInList;
 }
+#else
+// Helper function to know if a key should be captured
+// or if the event can be skipped because the key is only a modifier
+// that is not used alone in kicad
+bool isKeyModifierOnly( int aKeyCode )
+{
+    const enum wxKeyCode special_keys[] =
+    {
+        WXK_CONTROL, WXK_RAW_CONTROL, WXK_SHIFT,WXK_ALT
+    };
 
+    bool isInList = false;
 
-/* aHelper class that convert some special key codes to an equivalent.
+    for( unsigned ii = 0; ii < arrayDim( special_keys ) && !isInList; ii++ )
+    {
+        if( special_keys[ii] == aKeyCode )
+            isInList = true;
+    }
+
+    return isInList;
+}
+#endif
+
+/* A helper class that convert some special key codes to an equivalent.
  *  WXK_NUMPAD_UP to WXK_UP,
  *  WXK_NUMPAD_DOWN to WXK_DOWN,
  *  WXK_NUMPAD_LEFT to WXK_LEFT,
@@ -320,7 +341,7 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
 
     // Sometimes there is no window that has the focus (it happens when another PCB_BASE_FRAME
     // is opened and is iconized on Windows).
-    // In this case, give the focus to the parent frame (GAL canvas itself does not accept the 
+    // In this case, give the focus to the parent frame (GAL canvas itself does not accept the
     // focus when iconized for some obscure reason)
     if( wxWindow::FindFocus() == nullptr )
         m_toolMgr->GetEditFrame()->SetFocus();
@@ -370,17 +391,25 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
     {
         wxKeyEvent* ke = static_cast<wxKeyEvent*>( &aEvent );
         key = ke->GetKeyCode();
+#ifdef LEGACY_KEY_HANDLING
         keyIsSpecial = isKeySpecialCode( key );
+#else
+        keyIsSpecial = isKeyModifierOnly( key );
+#endif
         unicode = ke->GetUnicodeKey();
 
         wxLogTrace( kicadTraceKeyEvent, "TOOL_DISPATCHER::DispatchWxEvent %s", dump( *ke ) );
 
         // if the key event must be skipped, skip it here if the event is a wxEVT_CHAR_HOOK
         // and do nothing.
-        // a wxEVT_CHAR will be fired by wxWidgets later for this key.
         if( type == wxEVT_CHAR_HOOK )
         {
+#ifdef LEGACY_KEY_HANDLING
+            // a wxEVT_CHAR will be fired by wxWidgets later for this key.
             if( !keyIsSpecial )
+#else
+            if( keyIsSpecial )
+#endif
             {
                 aEvent.Skip();
                 return;

Follow ups

References