From 9d0ea66a96fe549a98177da79c141fc13543c33a Mon Sep 17 00:00:00 2001
From: Ian McInerney <Ian.S.McInerney@ieee.org>
Date: Sat, 6 Jun 2020 18:42:04 +0100
Subject: [PATCH] Don't use the accelerator table in the menubars

It seems that the accelerator table causes issues with
keyboard events on MSW.

Fixes https://gitlab.com/kicad/code/kicad/issues/1941
---
 3d-viewer/3d_viewer/3d_menubar.cpp   |  5 +--
 cvpcb/menubar.cpp                    |  3 +-
 eeschema/libedit/menubar_libedit.cpp |  5 +--
 eeschema/menubar.cpp                 |  5 +--
 eeschema/toolbars_lib_view.cpp       |  5 +--
 gerbview/menubar.cpp                 |  5 +--
 include/widgets/wx_menubar.h         | 51 ++++++++++++++++++++++++++++
 kicad/menubar.cpp                    |  3 +-
 pagelayout_editor/menubar.cpp        |  3 +-
 pcbnew/menubar_footprint_editor.cpp  |  5 +--
 pcbnew/menubar_pcb_editor.cpp        |  5 +--
 pcbnew/toolbars_footprint_viewer.cpp |  5 +--
 12 files changed, 81 insertions(+), 19 deletions(-)
 create mode 100644 include/widgets/wx_menubar.h

diff --git a/3d-viewer/3d_viewer/3d_menubar.cpp b/3d-viewer/3d_viewer/3d_menubar.cpp
index 76f5e3143d..a4e261d7e5 100644
--- a/3d-viewer/3d_viewer/3d_menubar.cpp
+++ b/3d-viewer/3d_viewer/3d_menubar.cpp
@@ -32,14 +32,15 @@
 #include <3d_viewer/tools/3d_actions.h>
 #include <tool/tool_manager.h>
 #include <tool/common_control.h>
+#include <widgets/wx_menubar.h>
 
 
 void EDA_3D_VIEWER::CreateMenuBar()
 {
     wxLogTrace( m_logTrace, "EDA_3D_VIEWER::CreateMenuBar" );
 
-    COMMON_CONTROL* tool = m_toolManager->GetTool<COMMON_CONTROL>();
-    wxMenuBar* menuBar   = new wxMenuBar;
+    COMMON_CONTROL* tool    = m_toolManager->GetTool<COMMON_CONTROL>();
+    WX_MENUBAR*     menuBar = new WX_MENUBAR();
 
 
     //-- File menu -----------------------------------------------------------
diff --git a/cvpcb/menubar.cpp b/cvpcb/menubar.cpp
index 89e86221ef..c16cd3bfa5 100644
--- a/cvpcb/menubar.cpp
+++ b/cvpcb/menubar.cpp
@@ -31,6 +31,7 @@
 
 #include <cvpcb_mainframe.h>
 #include <tools/cvpcb_actions.h>
+#include <widgets/wx_menubar.h>
 
 
 void CVPCB_MAINFRAME::ReCreateMenuBar()
@@ -39,7 +40,7 @@ void CVPCB_MAINFRAME::ReCreateMenuBar()
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
     wxMenuBar*  oldMenuBar = GetMenuBar();
-    wxMenuBar*  menuBar = new wxMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     //-- File menu -----------------------------------------------------------
     //
diff --git a/eeschema/libedit/menubar_libedit.cpp b/eeschema/libedit/menubar_libedit.cpp
index a5edf87b96..60a0f5d786 100644
--- a/eeschema/libedit/menubar_libedit.cpp
+++ b/eeschema/libedit/menubar_libedit.cpp
@@ -31,6 +31,7 @@
 #include <tools/ee_selection_tool.h>
 #include <lib_manager.h>
 #include "lib_edit_frame.h"
+#include <widgets/wx_menubar.h>
 
 
 void LIB_EDIT_FRAME::ReCreateMenuBar()
@@ -38,8 +39,8 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
     EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) {
         LIB_ID libId = getTargetLibId();
diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp
index 7cb4d3320a..ebb4fe7034 100644
--- a/eeschema/menubar.cpp
+++ b/eeschema/menubar.cpp
@@ -35,6 +35,7 @@
 #include <tools/ee_actions.h>
 #include "eeschema_id.h"
 #include "sch_edit_frame.h"
+#include <widgets/wx_menubar.h>
 
 extern void AddMenuLanguageList( CONDITIONAL_MENU* aMasterMenu, TOOL_INTERACTIVE* aControlTool );
 
@@ -44,8 +45,8 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
     EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     auto modifiedDocumentCondition = [&]( const SELECTION& sel )
                                      {
diff --git a/eeschema/toolbars_lib_view.cpp b/eeschema/toolbars_lib_view.cpp
index 2df4d24a73..532882f4f1 100644
--- a/eeschema/toolbars_lib_view.cpp
+++ b/eeschema/toolbars_lib_view.cpp
@@ -32,6 +32,7 @@
 #include <tool/tool_manager.h>
 #include <tools/ee_actions.h>
 #include <tools/lib_control.h>
+#include <widgets/wx_menubar.h>
 
 void LIB_VIEW_FRAME::ReCreateHToolbar()
 {
@@ -98,8 +99,8 @@ void LIB_VIEW_FRAME::ReCreateMenuBar()
     LIB_CONTROL* libControl = m_toolManager->GetTool<LIB_CONTROL>();
     // wxWidgets handles the OSX Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     //-- File menu -----------------------------------------------------------
     //
diff --git a/gerbview/menubar.cpp b/gerbview/menubar.cpp
index 8ff1a04725..593fead151 100644
--- a/gerbview/menubar.cpp
+++ b/gerbview/menubar.cpp
@@ -33,6 +33,7 @@
 #include <tool/tool_manager.h>
 #include <tools/gerbview_actions.h>
 #include <tools/gerbview_selection_tool.h>
+#include <widgets/wx_menubar.h>
 
 
 void GERBVIEW_FRAME::ReCreateMenuBar()
@@ -40,8 +41,8 @@ void GERBVIEW_FRAME::ReCreateMenuBar()
     GERBVIEW_SELECTION_TOOL* selTool = m_toolManager->GetTool<GERBVIEW_SELECTION_TOOL>();
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     //-- File menu -------------------------------------------------------
     //
diff --git a/include/widgets/wx_menubar.h b/include/widgets/wx_menubar.h
new file mode 100644
index 0000000000..5bcdb1e5c4
--- /dev/null
+++ b/include/widgets/wx_menubar.h
@@ -0,0 +1,51 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2020 KiCad Developers, see CHANGELOG.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
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef WX_MENUBAR_H_
+#define WX_MENUBAR_H_
+
+#include <wx/accel.h>
+#include <wx/menu.h>
+
+
+/**
+ * Wrapper around a wxMenuBar object that prevents the accelerator table from being used.
+ *
+ * It appears that on MSW the accelerator table of a wxMenuBar will be searched before key events are
+ * passed to other items. To work around this, simply don't let the menubar have an accelerator table.
+ * See https://gitlab.com/kicad/code/kicad/-/issues/1941
+ */
+class WX_MENUBAR : public wxMenuBar
+{
+public:
+    // Just take all constructors
+    using wxMenuBar::wxMenuBar;
+
+    void SetAcceleratorTable( const wxAcceleratorTable& aTable ) override
+    {
+        // Don't use the passed in accelerator table, create a new empty one
+        wxMenuBar::SetAcceleratorTable( wxAcceleratorTable() );
+    }
+};
+
+#endif // COMMON_WIDGETS_WX_BUSY_INDICATOR__H
diff --git a/kicad/menubar.cpp b/kicad/menubar.cpp
index f2ba1bd8ad..14b8836dad 100644
--- a/kicad/menubar.cpp
+++ b/kicad/menubar.cpp
@@ -34,6 +34,7 @@
 #include "kicad_manager_frame.h"
 #include "pgm_kicad.h"
 #include "kicad_id.h"
+#include <widgets/wx_menubar.h>
 
 
 void KICAD_MANAGER_FRAME::ReCreateMenuBar()
@@ -42,7 +43,7 @@ void KICAD_MANAGER_FRAME::ReCreateMenuBar()
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
     wxMenuBar*  oldMenuBar = GetMenuBar();
-    wxMenuBar*  menuBar = new wxMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     //-- File menu -----------------------------------------------------------
     //
diff --git a/pagelayout_editor/menubar.cpp b/pagelayout_editor/menubar.cpp
index e9064c0aad..9f34865921 100644
--- a/pagelayout_editor/menubar.cpp
+++ b/pagelayout_editor/menubar.cpp
@@ -34,6 +34,7 @@
 #include <tools/pl_selection_tool.h>
 #include "pl_editor_frame.h"
 #include "pl_editor_id.h"
+#include <widgets/wx_menubar.h>
 
 
 void PL_EDITOR_FRAME::ReCreateMenuBar()
@@ -42,7 +43,7 @@ void PL_EDITOR_FRAME::ReCreateMenuBar()
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
     wxMenuBar*  oldMenuBar = GetMenuBar();
-    wxMenuBar*  menuBar = new wxMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) {
         return IsContentModified();
diff --git a/pcbnew/menubar_footprint_editor.cpp b/pcbnew/menubar_footprint_editor.cpp
index 0e17a558f1..477587398d 100644
--- a/pcbnew/menubar_footprint_editor.cpp
+++ b/pcbnew/menubar_footprint_editor.cpp
@@ -36,6 +36,7 @@
 #include <tool/tool_manager.h>
 #include <tools/pcb_actions.h>
 #include <tools/selection_tool.h>
+#include <widgets/wx_menubar.h>
 
 
 void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
@@ -43,8 +44,8 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
     SELECTION_TOOL* selTool = m_toolManager->GetTool<SELECTION_TOOL>();
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     auto modifiedDocumentCondition = [this]( const SELECTION& sel ) {
         return IsContentModified();
diff --git a/pcbnew/menubar_pcb_editor.cpp b/pcbnew/menubar_pcb_editor.cpp
index 8dbf050bb7..c73ee9f95b 100644
--- a/pcbnew/menubar_pcb_editor.cpp
+++ b/pcbnew/menubar_pcb_editor.cpp
@@ -40,6 +40,7 @@
 #include <tool/tool_manager.h>
 #include <tools/pcb_actions.h>
 #include <tools/selection_tool.h>
+#include <widgets/wx_menubar.h>
 
 
 void PCB_EDIT_FRAME::ReCreateMenuBar()
@@ -47,8 +48,8 @@ void PCB_EDIT_FRAME::ReCreateMenuBar()
     SELECTION_TOOL* selTool = m_toolManager->GetTool<SELECTION_TOOL>();
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     auto modifiedDocumentCondition = [ this ] ( const SELECTION& sel ) {
         return IsContentModified();
diff --git a/pcbnew/toolbars_footprint_viewer.cpp b/pcbnew/toolbars_footprint_viewer.cpp
index acbba69063..da23a3e93a 100644
--- a/pcbnew/toolbars_footprint_viewer.cpp
+++ b/pcbnew/toolbars_footprint_viewer.cpp
@@ -30,6 +30,7 @@
 #include <tools/pcb_actions.h>
 #include "footprint_viewer_frame.h"
 #include "pcbnew_id.h"
+#include <widgets/wx_menubar.h>
 
 
 void FOOTPRINT_VIEWER_FRAME::ReCreateHToolbar()
@@ -160,8 +161,8 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateMenuBar()
     SELECTION_TOOL* selTool = m_toolManager->GetTool<SELECTION_TOOL>();
     // wxWidgets handles the Mac Application menu behind the scenes, but that means
     // we always have to start from scratch with a new wxMenuBar.
-    wxMenuBar* oldMenuBar = GetMenuBar();
-    wxMenuBar* menuBar = new wxMenuBar();
+    wxMenuBar*  oldMenuBar = GetMenuBar();
+    WX_MENUBAR* menuBar    = new WX_MENUBAR();
 
     //----- File menu -----------------------------------------------------------
     //