diff --git a/Terminal.Gui/Core/ContextMenu.cs b/Terminal.Gui/Core/ContextMenu.cs
index aeed58277..75869b2b4 100644
--- a/Terminal.Gui/Core/ContextMenu.cs
+++ b/Terminal.Gui/Core/ContextMenu.cs
@@ -132,7 +132,7 @@ namespace Terminal.Gui {
///
public void Hide ()
{
- menuBar.CloseAllMenus ();
+ menuBar.CleanUp ();
Dispose ();
}
@@ -196,5 +196,10 @@ namespace Terminal.Gui {
/// if the left or right position are negative.
///
public bool ForceMinimumPosToZero { get; set; } = true;
+
+ ///
+ /// Gets the that is hosting this context menu.
+ ///
+ public MenuBar MenuBar { get => menuBar; }
}
}
diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs
index 7006c5b0a..b8105dd4e 100644
--- a/Terminal.Gui/Views/Menu.cs
+++ b/Terminal.Gui/Views/Menu.cs
@@ -377,7 +377,7 @@ namespace Terminal.Gui {
class Menu : View {
internal MenuBarItem barItems;
- MenuBar host;
+ internal MenuBar host;
internal int current;
internal View previousSubFocused;
@@ -905,6 +905,11 @@ namespace Terminal.Gui {
// The right way to do this is to SetFocus(MenuBar), but for some reason
// that faults.
+ var mbar = GetMouseGrabViewInstance (this);
+ if (mbar != null) {
+ mbar.CleanUp ();
+ }
+
//Activate (0);
//StartMenu ();
IsMenuOpen = true;
@@ -1173,6 +1178,11 @@ namespace Terminal.Gui {
///
public void OpenMenu ()
{
+ var mbar = GetMouseGrabViewInstance (this);
+ if (mbar != null) {
+ mbar.CleanUp ();
+ }
+
if (openMenu != null)
return;
selected = 0;
@@ -1662,6 +1672,8 @@ namespace Terminal.Gui {
var menu = new Menu (this, i, 0, Menus [i]);
menu.Run (Menus [i].Action);
menu.Dispose ();
+ } else if (!IsMenuOpen) {
+ Activate (i);
}
} else if (me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1DoubleClicked || me.Flags == MouseFlags.Button1TripleClicked) {
if (IsMenuOpen && !Menus [i].IsTopLevel) {
@@ -1696,6 +1708,16 @@ namespace Terminal.Gui {
{
if (Application.mouseGrabView != null) {
if (me.View is MenuBar || me.View is Menu) {
+ var mbar = GetMouseGrabViewInstance (me.View);
+ if (mbar != null) {
+ if (me.Flags == MouseFlags.Button1Clicked) {
+ mbar.CleanUp ();
+ Application.GrabMouse (me.View);
+ } else {
+ handled = false;
+ return false;
+ }
+ }
if (me.View != current) {
Application.UngrabMouse ();
var v = me.View;
@@ -1791,6 +1813,30 @@ namespace Terminal.Gui {
return true;
}
+ MenuBar GetMouseGrabViewInstance (View view)
+ {
+ if (view == null || Application.mouseGrabView == null) {
+ return null;
+ }
+
+ MenuBar hostView = null;
+ if (view is MenuBar) {
+ hostView = (MenuBar)view;
+ } else if (view is Menu) {
+ hostView = ((Menu)view).host;
+ }
+
+ var grabView = Application.mouseGrabView;
+ MenuBar hostGrabView = null;
+ if (grabView is MenuBar) {
+ hostGrabView = (MenuBar)grabView;
+ } else if (grabView is Menu) {
+ hostGrabView = ((Menu)grabView).host;
+ }
+
+ return hostView != hostGrabView ? hostGrabView : null;
+ }
+
///
public override bool OnEnter (View view)
{
diff --git a/UnitTests/ContextMenuTests.cs b/UnitTests/ContextMenuTests.cs
index 291b952a6..0610e1f22 100644
--- a/UnitTests/ContextMenuTests.cs
+++ b/UnitTests/ContextMenuTests.cs
@@ -463,5 +463,57 @@ namespace Terminal.Gui.Core {
pos = GraphViewTests.AssertDriverContentsWithPosAre (expected, output);
Assert.Equal (new Point (1, 0), pos);
}
+
+ [Fact, AutoInitShutdown]
+ public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
+ {
+ var cm = new ContextMenu (10, 5,
+ new MenuBarItem (new MenuItem [] {
+ new MenuItem ("One", "", null),
+ new MenuItem ("Two", "", null)
+ })
+ );
+
+ var menu = new MenuBar (new MenuBarItem [] {
+ new MenuBarItem ("File", "", null),
+ new MenuBarItem ("Edit", "", null)
+ });
+
+ Application.Top.Add (menu);
+
+ Assert.Null (Application.mouseGrabView);
+
+ cm.Show ();
+ Assert.True (ContextMenu.IsShow);
+ Assert.Equal (cm.MenuBar, Application.mouseGrabView);
+ Assert.False (menu.IsMenuOpen);
+ Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));
+ Assert.False (ContextMenu.IsShow);
+ Assert.Equal (menu, Application.mouseGrabView);
+ Assert.True (menu.IsMenuOpen);
+
+ cm.Show ();
+ Assert.True (ContextMenu.IsShow);
+ Assert.Equal (cm.MenuBar, Application.mouseGrabView);
+ Assert.False (menu.IsMenuOpen);
+ Assert.False (menu.OnKeyDown (new KeyEvent (Key.Null, new KeyModifiers () { Alt = true })));
+ Assert.True (menu.OnKeyUp (new KeyEvent (Key.Null, new KeyModifiers () { Alt = true })));
+ Assert.False (ContextMenu.IsShow);
+ Assert.Equal (menu, Application.mouseGrabView);
+ Assert.True (menu.IsMenuOpen);
+
+ cm.Show ();
+ Assert.True (ContextMenu.IsShow);
+ Assert.Equal (cm.MenuBar, Application.mouseGrabView);
+ Assert.False (menu.IsMenuOpen);
+ Assert.False (menu.MouseEvent (new MouseEvent () { X = 1, Flags = MouseFlags.ReportMousePosition, View = menu }));
+ Assert.True (ContextMenu.IsShow);
+ Assert.Equal (cm.MenuBar, Application.mouseGrabView);
+ Assert.False (menu.IsMenuOpen);
+ Assert.True (menu.MouseEvent (new MouseEvent () { X = 1, Flags = MouseFlags.Button1Clicked, View = menu }));
+ Assert.False (ContextMenu.IsShow);
+ Assert.Equal (menu, Application.mouseGrabView);
+ Assert.True (menu.IsMenuOpen);
+ }
}
}