From 534ab2a6316ae152e5e9d7d6a7744002620b8728 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 14 Mar 2024 22:42:21 +0000 Subject: [PATCH 1/2] Fixes #3326. Menu is responding even outside the limits, not moving to the view that has the mouse. --- Terminal.Gui/Views/Menu/Menu.cs | 10 ++- UnitTests/Views/ContextMenuTests.cs | 123 +++++++++++++++++++++++++++- UnitTests/Views/MenuBarTests.cs | 22 +++++ 3 files changed, 149 insertions(+), 6 deletions(-) diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 0cc365595..d02791836 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -714,7 +714,7 @@ internal sealed class Menu : View private void Application_RootMouseEvent (object sender, MouseEventEventArgs a) { - if (a.MouseEvent.View is MenuBar) + if (a.MouseEvent.View is { } and (MenuBar or not Menu)) { return; } @@ -724,17 +724,19 @@ internal sealed class Menu : View throw new InvalidOperationException ("This shouldn't running on a invisible menu!"); } - Point boundsPoint = ScreenToBounds (a.MouseEvent.X, a.MouseEvent.Y); + View view = a.MouseEvent.View ?? this; + + Point boundsPoint = view.ScreenToBounds (a.MouseEvent.X, a.MouseEvent.Y); var me = new MouseEvent { X = boundsPoint.X, Y = boundsPoint.Y, Flags = a.MouseEvent.Flags, ScreenPosition = new (a.MouseEvent.X, a.MouseEvent.Y), - View = this + View = view }; - if (OnMouseEvent (me) || a.MouseEvent.Flags == MouseFlags.Button1Pressed || a.MouseEvent.Flags == MouseFlags.Button1Released) + if (view.OnMouseEvent (me) || a.MouseEvent.Flags == MouseFlags.Button1Pressed || a.MouseEvent.Flags == MouseFlags.Button1Released) { a.MouseEvent.Handled = true; } diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index ce7e93b9a..c4f34a11e 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -1306,9 +1306,10 @@ public class ContextMenuTests _output ); + // X=5 is the border and so need to use at least one more Application.OnMouseEvent ( new MouseEventEventArgs ( - new MouseEvent { X = 5, Y = 13, Flags = MouseFlags.Button1Clicked } + new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.Button1Clicked } ) ); @@ -1330,7 +1331,7 @@ public class ContextMenuTests Application.OnMouseEvent ( new MouseEventEventArgs ( - new MouseEvent { X = 5, Y = 12, Flags = MouseFlags.Button1Clicked } + new MouseEvent { X = 6, Y = 12, Flags = MouseFlags.Button1Clicked } ) ); @@ -1351,6 +1352,124 @@ public class ContextMenuTests Application.End (rs); } + [Fact] + [AutoInitShutdown] + public void UseSubMenusSingleFrame_False_By_Mouse () + { + var cm = new ContextMenu + { + Position = new Point (5, 10), + MenuItems = new MenuBarItem ( + "Numbers", + [ + new MenuItem ("One", "", null), + new MenuBarItem ( + "Two", + [ + new MenuItem ( + "Two-Menu 1", + "", + null + ), + new MenuItem ("Two-Menu 2", "", null) + ] + ), + new MenuBarItem ("Three", + [ + new MenuItem ( + "Three-Menu 1", + "", + null + ), + new MenuItem ("Three-Menu 2", "", null) + ] + ) + ] + ) + }; + + cm.Show (); + RunState rs = Application.Begin (Application.Top); + + Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); + + TestHelpers.AssertDriverContentsWithFrameAre ( + @" + ┌────────┐ + │ One │ + │ Two ►│ + │ Three ►│ + └────────┘", + _output + ); + + Application.OnMouseEvent ( + new MouseEventEventArgs ( + new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.ReportMousePosition } + ) + ); + + var firstIteration = false; + Application.RunIteration (ref rs, ref firstIteration); + Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); + + TestHelpers.AssertDriverContentsWithFrameAre ( + @" + ┌────────┐ + │ One │ + │ Two ►│┌─────────────┐ + │ Three ►││ Two-Menu 1 │ + └────────┘│ Two-Menu 2 │ + └─────────────┘", + _output + ); + + Application.OnMouseEvent ( + new MouseEventEventArgs ( + new MouseEvent { X = 6, Y = 14, Flags = MouseFlags.ReportMousePosition } + ) + ); + + firstIteration = false; + Application.RunIteration (ref rs, ref firstIteration); + Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); + + TestHelpers.AssertDriverContentsWithFrameAre ( + @" + ┌────────┐ + │ One │ + │ Two ►│ + │ Three ►│┌───────────────┐ + └────────┘│ Three-Menu 1 │ + │ Three-Menu 2 │ + └───────────────┘", + _output + ); + + Application.OnMouseEvent ( + new MouseEventEventArgs ( + new MouseEvent { X = 6, Y = 13, Flags = MouseFlags.ReportMousePosition } + ) + ); + + firstIteration = false; + Application.RunIteration (ref rs, ref firstIteration); + Assert.Equal (new Rectangle (5, 11, 10, 5), Application.Top.Subviews [0].Frame); + + TestHelpers.AssertDriverContentsWithFrameAre ( + @" + ┌────────┐ + │ One │ + │ Two ►│┌─────────────┐ + │ Three ►││ Two-Menu 1 │ + └────────┘│ Two-Menu 2 │ + └─────────────┘", + _output + ); + + Application.End (rs); + } + private ContextMenu Create_ContextMenu_With_Two_MenuItem (int x, int y) { return new ContextMenu diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 5e34fc0e0..118fd8191 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -3658,4 +3658,26 @@ Edit Add (menu); } } + + [Fact] + [AutoInitShutdown] + public void Click_Another_View_Close_A_Open_Menu () + { + var menu = new MenuBar + { + Menus = + [ + new MenuBarItem ("File", new MenuItem [] { new ("New", "", null) }) + ] + }; + + var btnClicked = false; + var btn = new Button { Y = 4, Text = "Test" }; + btn.Accept += (s, e) => btnClicked = true; + Application.Top.Add (menu, btn); + Application.Begin (Application.Top); + + Application.OnMouseEvent (new (new () { X = 0, Y = 4, Flags = MouseFlags.Button1Clicked })); + Assert.True (btnClicked); + } } From 2b3a67c7a9377eef1c8bf989271d85a91cc26814 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 14 Mar 2024 23:02:23 +0000 Subject: [PATCH 2/2] Fix typo. --- UnitTests/Views/MenuBarTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 118fd8191..6f5f6b8bd 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -3661,7 +3661,7 @@ Edit [Fact] [AutoInitShutdown] - public void Click_Another_View_Close_A_Open_Menu () + public void Click_Another_View_Close_An_Open_Menu () { var menu = new MenuBar {