瀏覽代碼

ix some more bug, cleanup code and add more unit tests.

BDisp 11 月之前
父節點
當前提交
fa0085d9e4

+ 1 - 1
Terminal.Gui/Views/ColorPicker.cs

@@ -361,7 +361,7 @@ public class ColorPicker : View
         }
     }
 
-
+    /// <inheritdoc />
     protected override void Dispose (bool disposing)
     {
         DisposeOldViews ();

+ 4 - 4
Terminal.Gui/Views/Menu/ContextMenu.cs

@@ -58,7 +58,7 @@ public sealed class ContextMenu : IDisposable
     public static bool IsShow { get; private set; }
 
     /// <summary>Specifies the key that will activate the context menu.</summary>
-    public new Key Key
+    public Key Key
     {
         get => _key;
         set
@@ -133,7 +133,7 @@ public sealed class ContextMenu : IDisposable
             return;
         }
 
-        foreach (var menuItem in menuBarItem.Children!)
+        foreach (MenuItem? menuItem in menuBarItem.Children!)
         {
             // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
             if (menuItem is null)
@@ -150,7 +150,7 @@ public sealed class ContextMenu : IDisposable
                 if (menuItem.ShortcutKey != Key.Empty)
                 {
                     // Remove an existent ShortcutKey
-                    _menuBar?.KeyBindings.Remove (menuItem.ShortcutKey);
+                    _menuBar?.KeyBindings.Remove (menuItem.ShortcutKey!);
                 }
             }
         }
@@ -171,7 +171,7 @@ public sealed class ContextMenu : IDisposable
             Dispose ();
         }
 
-        if (menuItems is null || menuItems.Children.Length == 0)
+        if (menuItems is null || menuItems.Children!.Length == 0)
         {
             return;
         }

+ 1 - 1
Terminal.Gui/Views/Menu/Menu.cs

@@ -13,7 +13,7 @@ internal sealed class Menu : View
     internal int _currentChild;
     internal View? _previousSubFocused;
 
-    internal static Rectangle MakeFrame (int x, int y, MenuItem []? items, Menu? parent = null)
+    internal static Rectangle MakeFrame (int x, int y, MenuItem? []? items, Menu? parent = null)
     {
         if (items is null || items.Length == 0)
         {

+ 20 - 8
Terminal.Gui/Views/Menu/MenuBar.cs

@@ -126,7 +126,12 @@ public class MenuBar : View, IDesignable
                         return true;
                     }
                    );
-        AddCommand (Command.ToggleExpandCollapse, ctx => Select (Menus.IndexOf (ctx.KeyBinding?.Context)));
+        AddCommand (Command.ToggleExpandCollapse, ctx =>
+                                                  {
+                                                      CloseOtherOpenedMenuBar ();
+
+                                                      return Select (Menus.IndexOf (ctx.KeyBinding?.Context));
+                                                  });
         AddCommand (Command.Select, ctx =>
                                     {
                                         var res =  Run ((ctx.KeyBinding?.Context as MenuItem)?.Action!);
@@ -387,6 +392,8 @@ public class MenuBar : View, IDesignable
 
         mbar?.CleanUp ();
 
+        CloseOtherOpenedMenuBar ();
+
         if (!Enabled || _openMenu is { })
         {
             return;
@@ -528,11 +535,16 @@ public class MenuBar : View, IDesignable
         _openedByAltKey = false;
         OnMenuAllClosed ();
 
+        CloseOtherOpenedMenuBar ();
+    }
+
+    private void CloseOtherOpenedMenuBar ()
+    {
         if (Application.Current is { })
         {
             // Close others menu bar opened
-            View? cm = Application.Current.Subviews.FirstOrDefault (v => v is Menu cm && cm.Host != this && cm.Host.IsMenuOpen);
-            (cm as Menu)?.Host.CleanUp ();
+            Menu? menu = Application.Current.Subviews.FirstOrDefault (v => v is Menu m && m.Host != this && m.Host.IsMenuOpen) as Menu;
+            menu?.Host.CleanUp ();
         }
     }
 
@@ -726,7 +738,7 @@ public class MenuBar : View, IDesignable
                     else if (subMenu != null
                              || (OpenCurrentMenu._currentChild > -1
                                  && !OpenCurrentMenu.BarItems!
-                                                    .Children! [OpenCurrentMenu._currentChild]
+                                                    .Children! [OpenCurrentMenu._currentChild]!
                                                     .IsFromSubMenu))
                     {
                         _selectedSub++;
@@ -999,7 +1011,7 @@ public class MenuBar : View, IDesignable
     }
 
     internal bool SelectEnabledItem (
-        IEnumerable<MenuItem>? children,
+        MenuItem? []? children,
         int current,
         out int newCurrent,
         bool forward = true
@@ -1012,11 +1024,11 @@ public class MenuBar : View, IDesignable
             return true;
         }
 
-        IEnumerable<MenuItem> childMenuItems = forward ? children : children.Reverse ();
+        IEnumerable<MenuItem?> childMenuItems = forward ? children : children.Reverse ();
 
         int count;
 
-        IEnumerable<MenuItem> menuItems = childMenuItems as MenuItem [] ?? childMenuItems.ToArray ();
+        IEnumerable<MenuItem?> menuItems = childMenuItems as MenuItem [] ?? childMenuItems.ToArray ();
 
         if (forward)
         {
@@ -1027,7 +1039,7 @@ public class MenuBar : View, IDesignable
             count = menuItems.Count ();
         }
 
-        foreach (MenuItem child in menuItems)
+        foreach (MenuItem? child in menuItems)
         {
             if (forward)
             {

+ 2 - 2
Terminal.Gui/Views/Menu/MenuItem.cs

@@ -351,10 +351,10 @@ public class MenuItem
     {
         if (Parent is { })
         {
-            MenuItem []? childrens = ((MenuBarItem)Parent).Children;
+            MenuItem? []? childrens = ((MenuBarItem)Parent).Children;
             var i = 0;
 
-            foreach (MenuItem c in childrens!)
+            foreach (MenuItem? c in childrens!)
             {
                 if (c != this)
                 {

+ 6 - 6
UICatalog/Scenarios/ContextMenus.cs

@@ -98,8 +98,8 @@ public class ContextMenus : Scenario
             Menus =
             [
                 new (
-                     "File",
-                     new MenuItem [] { new ("Quit", "", () => Application.RequestStop (), null, null, Application.QuitKey) })
+                     "_File",
+                     new MenuItem [] { new ("_Quit", "", () => Application.RequestStop (), null, null, Application.QuitKey) })
             ]
         };
 
@@ -170,6 +170,10 @@ public class ContextMenus : Scenario
         MenuBarItem menuItems = new (
                                      new []
                                      {
+                                         new MenuBarItem (
+                                                          "_Languages",
+                                                          GetSupportedCultures ()
+                                                         ),
                                          new (
                                               "_Configuration",
                                               "Show configuration",
@@ -214,10 +218,6 @@ public class ContextMenus : Scenario
                                                                   )
                                                           }
                                                          ),
-                                         new MenuBarItem (
-                                                          "_Languages",
-                                                          GetSupportedCultures ()
-                                                         ),
                                          _miForceMinimumPosToZero =
                                              new (
                                                   "Fo_rceMinimumPosToZero",

+ 27 - 17
UICatalog/Scenarios/DynamicMenuBar.cs

@@ -875,7 +875,7 @@ public class DynamicMenuBar : Scenario
                                   {
                                       MenuItem newMenu = CreateNewMenu (item, _currentMenuBarItem);
                                       var menuBarItem = _currentMenuBarItem as MenuBarItem;
-                                      menuBarItem.AddMenuBarItem (newMenu);
+                                      menuBarItem.AddMenuBarItem (MenuBar, newMenu);
 
 
                                       DataContext.Menus.Add (new () { Title = newMenu.Title, MenuItem = newMenu });
@@ -915,6 +915,11 @@ public class DynamicMenuBar : Scenario
                                             _lstMenus.SelectedItem = _lstMenus.Source.Count - 1;
                                         }
 
+                                        if (_menuBar.Menus.Length == 0)
+                                        {
+                                            RemoveMenuBar ();
+                                        }
+
                                         _lstMenus.SetNeedsDisplay ();
                                         SetFrameDetails ();
                                     }
@@ -992,7 +997,7 @@ public class DynamicMenuBar : Scenario
                                          }
 
                                          var newMenu = CreateNewMenu (item) as MenuBarItem;
-                                         newMenu.AddMenuBarItem ();
+                                         newMenu.AddMenuBarItem (MenuBar);
 
                                          _currentMenuBarItem = newMenu;
                                          _currentMenuBarItem.CheckType = item.CheckStyle;
@@ -1012,7 +1017,7 @@ public class DynamicMenuBar : Scenario
 
             btnRemoveMenuBar.Accept += (s, e) =>
                                         {
-                                            if (_menuBar == null || _menuBar.Menus.Length == 0)
+                                            if (_menuBar == null)
                                             {
                                                 return;
                                             }
@@ -1033,25 +1038,30 @@ public class DynamicMenuBar : Scenario
                                                                           : null;
                                             }
 
-                                            if (MenuBar != null && _currentMenuBarItem == null && _menuBar.Menus.Length == 0)
-                                            {
-                                                Remove (_menuBar);
-                                                _menuBar.Dispose ();
-                                                _menuBar = null;
-                                                DataContext.Menus = new ();
-                                                _currentMenuBarItem = null;
-                                                _currentSelectedMenuBar = -1;
-                                                lblMenuBar.Text = string.Empty;
-                                            }
-                                            else
-                                            {
-                                                lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
-                                            }
+                                            RemoveMenuBar ();
 
                                             SetListViewSource (_currentMenuBarItem, true);
                                             SetFrameDetails ();
                                         };
 
+            void RemoveMenuBar ()
+            {
+                if (MenuBar != null && _currentMenuBarItem == null && _menuBar.Menus.Length == 0)
+                {
+                    Remove (_menuBar);
+                    _menuBar.Dispose ();
+                    _menuBar = null;
+                    DataContext.Menus = new ();
+                    _currentMenuBarItem = null;
+                    _currentSelectedMenuBar = -1;
+                    lblMenuBar.Text = string.Empty;
+                }
+                else
+                {
+                    lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
+                }
+            }
+
             SetFrameDetails ();
 
             var ustringConverter = new UStringValueConverter ();

+ 1 - 1
UICatalog/UICatalog.cs

@@ -875,7 +875,7 @@ public class UICatalogApp
                 };
             }
 
-            Enum GetDiagnosticsEnumValue (string title)
+            Enum GetDiagnosticsEnumValue (string? title)
             {
                 return title switch
                 {

+ 289 - 18
UnitTests/Views/ContextMenuTests.cs

@@ -19,10 +19,10 @@ public class ContextMenuTests (ITestOutputHelper output)
         cm.Position = new Point (20, 10);
 
         var menuItems = new MenuBarItem (
-                                        [
-                                            new MenuItem ("First", "", null)
-                                        ]
-                                       );
+                                         [
+                                             new MenuItem ("First", "", null)
+                                         ]
+                                        );
         cm.Show (menuItems);
         Assert.Equal (new Point (20, 10), cm.Position);
         Assert.Single (cm.MenuItems!.Children);
@@ -42,6 +42,7 @@ public class ContextMenuTests (ITestOutputHelper output)
 
         var view = new View { X = 5, Y = 10 };
         top.Add (view);
+
         cm = new ContextMenu
         {
             Host = view,
@@ -74,6 +75,7 @@ public class ContextMenuTests (ITestOutputHelper output)
                                              new MenuItem ("Two", "", null)
                                          ]
                                         );
+
         var menu = new MenuBar
         {
             Menus =
@@ -401,6 +403,7 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey));
         Assert.True (tf.ContextMenu.MenuBar!.IsMenuOpen);
         Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey));
+
         // The last context menu bar opened is always preserved
         Assert.NotNull (tf.ContextMenu.MenuBar);
         top.Dispose ();
@@ -529,8 +532,8 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (
                      top.Subviews [0]
                         .NewMouseEvent (
-                                     new MouseEvent { Position = new (0, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
-                                    )
+                                        new MouseEvent { Position = new (0, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
+                                       )
                     );
         Application.Refresh ();
         Assert.Equal (new Point (-1, -2), cm.Position);
@@ -577,8 +580,8 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (
                      top.Subviews [0]
                         .NewMouseEvent (
-                                     new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
-                                    )
+                                        new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
+                                       )
                     );
         Application.Refresh ();
         Assert.Equal (new Point (41, -2), cm.Position);
@@ -624,8 +627,8 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (
                      top.Subviews [0]
                         .NewMouseEvent (
-                                     new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
-                                    )
+                                        new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
+                                       )
                     );
         Application.Refresh ();
         Assert.Equal (new Point (41, 9), cm.Position);
@@ -668,8 +671,8 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (
                      top.Subviews [0]
                         .NewMouseEvent (
-                                     new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
-                                    )
+                                        new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
+                                       )
                     );
         Application.Refresh ();
         Assert.Equal (new Point (41, 22), cm.Position);
@@ -712,8 +715,8 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (
                      top.Subviews [0]
                         .NewMouseEvent (
-                                     new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
-                                    )
+                                        new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] }
+                                       )
                     );
         Application.Refresh ();
         Assert.Equal (new Point (19, 10), cm.Position);
@@ -1408,6 +1411,7 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (tf1.HasFocus);
         Assert.False (tf2.HasFocus);
         Assert.Equal (4, win.Subviews.Count);
+
         // The last context menu bar opened is always preserved
         Assert.NotNull (tf2.ContextMenu.MenuBar);
         Assert.Equal (win.Focused, tf1);
@@ -1419,6 +1423,7 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.False (tf1.HasFocus);
         Assert.True (tf2.HasFocus);
         Assert.Equal (4, win.Subviews.Count);
+
         // The last context menu bar opened is always preserved
         Assert.NotNull (tf2.ContextMenu.MenuBar);
         Assert.Equal (win.Focused, tf2);
@@ -1447,7 +1452,7 @@ public class ContextMenuTests (ITestOutputHelper output)
 
     [Fact]
     [AutoInitShutdown]
-    public void KeyBinding_Removed_On_Close_ContextMenu ()
+    public void KeyBindings_Removed_On_Close_ContextMenu ()
     {
         var newFile = false;
         var renameFile = false;
@@ -1539,7 +1544,7 @@ public class ContextMenuTests (ITestOutputHelper output)
 
         var menuItems = new MenuBarItem (
                                          [
-                                             new MenuItem ("Rename File", string.Empty, Rename, null, null, Key.R.WithCtrl),
+                                             new ("Rename File", string.Empty, Rename, null, null, Key.R.WithCtrl),
                                          ]
                                         );
         var top = new Toplevel ();
@@ -1618,7 +1623,7 @@ public class ContextMenuTests (ITestOutputHelper output)
 
         var menuItems = new MenuBarItem (
                                          [
-                                             new MenuItem ("New File", string.Empty, NewContextMenu, null, null, Key.N.WithCtrl),
+                                             new ("New File", string.Empty, NewContextMenu, null, null, Key.N.WithCtrl),
                                          ]
                                         );
         var top = new Toplevel ();
@@ -1643,6 +1648,7 @@ public class ContextMenuTests (ITestOutputHelper output)
         Assert.True (Application.OnKeyDown (Key.N.WithCtrl));
         Application.MainLoop!.RunIteration ();
         Assert.False (newMenuBar);
+
         // The most focused shortcut is executed
         Assert.True (newContextMenu);
         Assert.False (cm.MenuBar!.IsMenuOpen);
@@ -1663,4 +1669,269 @@ public class ContextMenuTests (ITestOutputHelper output)
 
         void NewContextMenu () { newContextMenu = true; }
     }
-}
+
+    [Fact]
+    [AutoInitShutdown]
+    public void HotKeys_Removed_On_Close_ContextMenu ()
+    {
+        var newFile = false;
+        var renameFile = false;
+        var deleteFile = false;
+
+        var cm = new ContextMenu ();
+
+        var menuItems = new MenuBarItem (
+                                         [
+                                             new ("_New File", string.Empty, New, null, null),
+                                             new ("_Rename File", string.Empty, Rename, null, null),
+                                             new ("_Delete File", string.Empty, Delete, null, null)
+                                         ]
+                                        );
+        var top = new Toplevel ();
+        Application.Begin (top);
+
+        Assert.Null (cm.MenuBar);
+        Assert.False (Application.OnKeyDown (Key.N.WithAlt));
+        Assert.False (Application.OnKeyDown (Key.R.WithAlt));
+        Assert.False (Application.OnKeyDown (Key.D.WithAlt));
+        Assert.False (newFile);
+        Assert.False (renameFile);
+        Assert.False (deleteFile);
+
+        cm.Show (menuItems);
+        Assert.True (cm.MenuBar!.IsMenuOpen);
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.N.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.D.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.D.NoShift));
+        Assert.Single (Application.Current!.Subviews);
+        View [] menus = Application.Current!.Subviews.Where (v => v is Menu m && m.Host == cm.MenuBar).ToArray ();
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.N.NoShift));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.D.WithAlt));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.D.NoShift));
+
+        Assert.True (Application.OnKeyDown (Key.N.WithAlt));
+        Assert.False (cm.MenuBar!.IsMenuOpen);
+        Application.MainLoop!.RunIteration ();
+        Assert.True (newFile);
+        cm.Show (menuItems);
+        Assert.True (Application.OnKeyDown (Key.R.WithAlt));
+        Assert.False (cm.MenuBar.IsMenuOpen);
+        Application.MainLoop!.RunIteration ();
+        Assert.True (renameFile);
+        cm.Show (menuItems);
+        Assert.True (Application.OnKeyDown (Key.D.WithAlt));
+        Assert.False (cm.MenuBar.IsMenuOpen);
+        Application.MainLoop!.RunIteration ();
+        Assert.True (deleteFile);
+
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.N.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.D.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.D.NoShift));
+
+        newFile = false;
+        renameFile = false;
+        deleteFile = false;
+        Assert.False (Application.OnKeyDown (Key.N.WithAlt));
+        Assert.False (Application.OnKeyDown (Key.R.WithAlt));
+        Assert.False (Application.OnKeyDown (Key.D.WithAlt));
+        Assert.False (newFile);
+        Assert.False (renameFile);
+        Assert.False (deleteFile);
+
+        top.Dispose ();
+
+        void New () { newFile = true; }
+
+        void Rename () { renameFile = true; }
+
+        void Delete () { deleteFile = true; }
+    }
+
+    [Fact]
+    [AutoInitShutdown]
+    public void HotKeys_With_ContextMenu_And_MenuBar ()
+    {
+        var newFile = false;
+        var renameFile = false;
+
+        var menuBar = new MenuBar
+        {
+            Menus =
+            [
+                new (
+                     "_File",
+                     new MenuItem []
+                     {
+                         new ("_New", string.Empty, New)
+                     })
+            ]
+        };
+        var cm = new ContextMenu ();
+
+        var menuItems = new MenuBarItem (
+                                         [
+                                             new MenuBarItem (
+                                                              "_Edit",
+                                                              new MenuItem []
+                                                              {
+                                                                  new ("_Rename File", string.Empty, Rename)
+                                                              }
+                                                             )
+                                         ]
+                                        );
+        var top = new Toplevel ();
+        top.Add (menuBar);
+        Application.Begin (top);
+
+        Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.F.WithAlt));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        View [] menus = Application.Current!.Subviews.Where (v => v is Menu m && m.Host == menuBar).ToArray ();
+        Assert.Empty (menus);
+        Assert.Null (cm.MenuBar);
+
+        Assert.True (Application.OnKeyDown (Key.F.WithAlt));
+        Assert.True (menuBar.IsMenuOpen);
+        Assert.Equal (2, Application.Current!.Subviews.Count);
+        menus = Application.Current!.Subviews.Where (v => v is Menu m && m.Host == menuBar).ToArray ();
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.True (Application.OnKeyDown (Key.N.WithAlt));
+        Assert.False (menuBar.IsMenuOpen);
+        Assert.False (Application.OnKeyDown (Key.R.WithAlt));
+        Application.MainLoop!.RunIteration ();
+        Assert.True (newFile);
+        Assert.False (renameFile);
+
+        newFile = false;
+
+        cm.Show (menuItems);
+        Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.F.WithAlt));
+        Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.F.NoShift));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.NoShift));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.E.WithAlt));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.E.NoShift));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.True (cm.MenuBar!.IsMenuOpen);
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.F.WithAlt));
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.F.NoShift));
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.N.NoShift));
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.E.WithAlt));
+        Assert.False (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.E.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.Equal (3, Application.Current!.Subviews.Count);
+        menus = Application.Current!.Subviews.Where (v => v is Menu m && m.Host == cm.MenuBar).ToArray ();
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.E.WithAlt));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.E.NoShift));
+        Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.True (cm.MenuBar.IsMenuOpen);
+        Assert.True (Application.OnKeyDown (Key.F.WithAlt));
+        Assert.False (cm.MenuBar.IsMenuOpen);
+        Assert.True (Application.OnKeyDown (Key.N.WithAlt));
+        Application.MainLoop!.RunIteration ();
+        Assert.True (newFile);
+
+        cm.Show (menuItems);
+        Assert.True (cm.MenuBar.IsMenuOpen);
+        Assert.Equal (3, Application.Current!.Subviews.Count);
+        menus = Application.Current!.Subviews.Where (v => v is Menu m && m.Host == cm.MenuBar).ToArray ();
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.E.WithAlt));
+        Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.E.NoShift));
+        Assert.False (menus [0].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.False (menus [0].KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.False (menus [1].KeyBindings.Bindings.ContainsKey (Key.E.WithAlt));
+        Assert.False (menus [1].KeyBindings.Bindings.ContainsKey (Key.E.NoShift));
+        Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+        Assert.True (Application.OnKeyDown (Key.E.NoShift));
+        Assert.True (Application.OnKeyDown (Key.R.WithAlt));
+        Assert.False (cm.MenuBar.IsMenuOpen);
+        Application.MainLoop!.RunIteration ();
+        Assert.True (renameFile);
+
+        Assert.Single (Application.Current!.Subviews);
+        Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.F.WithAlt));
+        Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.F.NoShift));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.WithAlt));
+        Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.E.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.E.NoShift));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithAlt));
+        Assert.False (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.NoShift));
+
+        newFile = false;
+        renameFile = false;
+        Assert.True (Application.OnKeyDown (Key.F.WithAlt));
+        Assert.True (Application.OnKeyDown (Key.N.WithAlt));
+        Assert.False (Application.OnKeyDown (Key.R.WithAlt));
+        Application.MainLoop!.RunIteration ();
+        Assert.True (newFile);
+        Assert.False (renameFile);
+
+        top.Dispose ();
+
+        void New () { newFile = true; }
+
+        void Rename () { renameFile = true; }
+    }
+
+    [Fact]
+    [AutoInitShutdown]
+    public void Opened_MenuBar_Is_Closed_When_Another_MenuBar_Is_Opening_Also_By_HotKey ()
+    {
+        var menuBar = new MenuBar
+        {
+            Menus =
+            [
+                new (
+                     "_File",
+                     new MenuItem []
+                     {
+                         new ("_New", string.Empty, null)
+                     })
+            ]
+        };
+        var cm = new ContextMenu ();
+
+        var menuItems = new MenuBarItem (
+                                         [
+                                             new MenuBarItem (
+                                                              "_Edit",
+                                                              new MenuItem []
+                                                              {
+                                                                  new ("_Rename File", string.Empty, null)
+                                                              }
+                                                             )
+                                         ]
+                                        );
+        var top = new Toplevel ();
+        top.Add (menuBar);
+        Application.Begin (top);
+
+        Assert.True (Application.OnKeyDown (Key.F.WithAlt));
+        Assert.True (menuBar.IsMenuOpen);
+
+        cm.Show (menuItems);
+        Assert.False (menuBar.IsMenuOpen);
+        Assert.True (cm.MenuBar!.IsMenuOpen);
+
+        Assert.True (Application.OnKeyDown (Key.F.WithAlt));
+        Assert.True (menuBar.IsMenuOpen);
+        Assert.False (cm.MenuBar!.IsMenuOpen);
+
+        top.Dispose ();
+    }
+}