Skip to content

Commit 76a14d4

Browse files
authored
Fixes #3986. ContextMenus now broken in v2 net and win drivers (#3987)
1 parent ce7fc04 commit 76a14d4

File tree

3 files changed

+73
-47
lines changed

3 files changed

+73
-47
lines changed

Terminal.Gui/Views/Menu/MenuBar.cs

+25-12
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,15 @@ out OpenCurrentMenu._currentChild
441441
return;
442442
}
443443

444-
Application.GrabMouse (this);
444+
if (_isContextMenuLoading)
445+
{
446+
Application.GrabMouse (_openMenu);
447+
_isContextMenuLoading = false;
448+
}
449+
else
450+
{
451+
Application.GrabMouse (this);
452+
}
445453
}
446454

447455
/// <inheritdoc/>
@@ -493,6 +501,11 @@ internal void Activate (int idx, int sIdx = -1, MenuBarItem? subMenu = null!)
493501

494502
internal void CleanUp ()
495503
{
504+
if (_isCleaning)
505+
{
506+
return;
507+
}
508+
496509
_isCleaning = true;
497510

498511
if (_openMenu is { })
@@ -1448,9 +1461,9 @@ protected override bool OnMouseEvent (MouseEventArgs me)
14481461
Activate (i);
14491462
}
14501463
}
1451-
else if (me.Flags == MouseFlags.Button1Pressed
1452-
|| me.Flags == MouseFlags.Button1DoubleClicked
1453-
|| me.Flags == MouseFlags.Button1TripleClicked)
1464+
else if (me.Flags.HasFlag (MouseFlags.Button1Pressed)
1465+
|| me.Flags.HasFlag (MouseFlags.Button1DoubleClicked)
1466+
|| me.Flags.HasFlag (MouseFlags.Button1TripleClicked))
14541467
{
14551468
if (IsMenuOpen && !Menus [i].IsTopLevel)
14561469
{
@@ -1534,16 +1547,17 @@ internal bool HandleGrabView (MouseEventArgs me, View current)
15341547
}
15351548
}
15361549

1537-
if (me.View != current)
1550+
if (Application.MouseGrabView != me.View)
15381551
{
1539-
View v = current;
1540-
Application.UngrabMouse ();
1552+
View v = me.View;
1553+
Application.GrabMouse (v);
15411554

1542-
if (((Menu)me.View).Host.SuperView is { } && ((Menu)me.View).Host.SuperView!.InternalSubViews.Contains(me.View))
1543-
{
1544-
v = me.View;
1545-
}
1555+
return true;
1556+
}
15461557

1558+
if (me.View != current)
1559+
{
1560+
View v = me.View;
15471561
Application.GrabMouse (v);
15481562
MouseEventArgs nme;
15491563

@@ -1590,7 +1604,6 @@ internal bool HandleGrabView (MouseEventArgs me, View current)
15901604
else
15911605
{
15921606
_handled = false;
1593-
_isContextMenuLoading = false;
15941607

15951608
return false;
15961609
}

Tests/UnitTests/Views/ContextMenuTests.cs

+28-25
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
7676
]
7777
);
7878

79-
var menu = new MenuBar
79+
var menuBar = new MenuBar
8080
{
8181
Menus =
8282
[
@@ -86,24 +86,26 @@ public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
8686
};
8787

8888
var top = new Toplevel ();
89-
top.Add (menu);
89+
top.Add (menuBar);
9090
Application.Begin (top);
9191

9292
Assert.Null (Application.MouseGrabView);
9393

9494
cm.Show (menuItems);
9595
Assert.True (ContextMenu.IsShow);
96-
Assert.Equal (cm.MenuBar, Application.MouseGrabView);
97-
Assert.False (menu.IsMenuOpen);
98-
Assert.True (menu.NewKeyDownEvent (menu.Key));
99-
Assert.False (ContextMenu.IsShow);
96+
Menu menu = (Menu)top.SubViews.First (v => v is Menu);
10097
Assert.Equal (menu, Application.MouseGrabView);
101-
Assert.True (menu.IsMenuOpen);
98+
Assert.False (menuBar.IsMenuOpen);
99+
Assert.True (menuBar.NewKeyDownEvent (menuBar.Key));
100+
Assert.False (ContextMenu.IsShow);
101+
Assert.Equal (menuBar, Application.MouseGrabView);
102+
Assert.True (menuBar.IsMenuOpen);
102103

103104
cm.Show (menuItems);
104105
Assert.True (ContextMenu.IsShow);
105-
Assert.Equal (cm.MenuBar, Application.MouseGrabView);
106-
Assert.False (menu.IsMenuOpen);
106+
menu = (Menu)top.SubViews.First (v => v is Menu);
107+
Assert.Equal (menu, Application.MouseGrabView);
108+
Assert.False (menuBar.IsMenuOpen);
107109
#if SUPPORT_ALT_TO_ACTIVATE_MENU
108110
Assert.True (Application.Top.ProcessKeyUp (new (Key.AltMask)));
109111
Assert.False (ContextMenu.IsShow);
@@ -113,16 +115,17 @@ public void ContextMenu_Is_Closed_If_Another_MenuBar_Is_Open_Or_Vice_Versa ()
113115

114116
cm.Show (menuItems);
115117
Assert.True (ContextMenu.IsShow);
116-
Assert.Equal (cm.MenuBar, Application.MouseGrabView);
117-
Assert.False (menu.IsMenuOpen);
118-
Assert.False (menu.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu }));
118+
menu = (Menu)top.SubViews.First (v => v is Menu);
119+
Assert.Equal (menu, Application.MouseGrabView);
120+
Assert.False (menuBar.IsMenuOpen);
121+
Assert.False (menuBar.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menuBar }));
119122
Assert.True (ContextMenu.IsShow);
120-
Assert.Equal (cm.MenuBar, Application.MouseGrabView);
121-
Assert.False (menu.IsMenuOpen);
122-
Assert.True (menu.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1Clicked, View = menu }));
123-
Assert.False (ContextMenu.IsShow);
124123
Assert.Equal (menu, Application.MouseGrabView);
125-
Assert.True (menu.IsMenuOpen);
124+
Assert.False (menuBar.IsMenuOpen);
125+
Assert.True (menuBar.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1Clicked, View = menuBar }));
126+
Assert.False (ContextMenu.IsShow);
127+
Assert.Equal (menuBar, Application.MouseGrabView);
128+
Assert.True (menuBar.IsMenuOpen);
126129
top.Dispose ();
127130
}
128131

@@ -1423,7 +1426,7 @@ public void Handling_TextField_With_Opened_ContextMenu_By_Mouse_HasFocus ()
14231426
Assert.Equal (6, win.SubViews.Count);
14241427
Assert.True (tf2.ContextMenu.MenuBar.IsMenuOpen);
14251428
Assert.True (win.Focused is Menu);
1426-
Assert.True (Application.MouseGrabView is MenuBar);
1429+
Assert.True (Application.MouseGrabView is Menu);
14271430
Assert.Equal (tf2, Application._cachedViewsUnderMouse.LastOrDefault ());
14281431

14291432
// Click on tf1 to focus it, which cause context menu being closed
@@ -2026,39 +2029,39 @@ public void Mouse_Pressed_Released_Clicked (int button)
20262029
// Right Button
20272030
case 3:
20282031
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 2), Flags = MouseFlags.Button3Pressed });
2029-
Assert.False (menuBar.IsMenuOpen);
2032+
Assert.True (menuBar.IsMenuOpen);
20302033
Application.MainLoop.RunIteration ();
20312034
Assert.False (actionRaised);
20322035
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 2), Flags = MouseFlags.Button3Released });
2033-
Assert.False (menuBar.IsMenuOpen);
2036+
Assert.True (menuBar.IsMenuOpen);
20342037
Application.MainLoop.RunIteration ();
20352038
Assert.False (actionRaised);
20362039
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 2), Flags = MouseFlags.Button3Clicked });
2037-
Assert.False (menuBar.IsMenuOpen);
2040+
Assert.True (menuBar.IsMenuOpen);
20382041
Application.MainLoop.RunIteration ();
20392042
Assert.False (actionRaised);
20402043

20412044
break;
20422045
}
20432046

20442047
// ContextMenu
2045-
Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 2), Flags = cm.MouseFlags });
2048+
Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 4), Flags = cm.MouseFlags });
20462049
Assert.False (menuBar.IsMenuOpen);
20472050
Assert.True (cm.MenuBar!.IsMenuOpen);
20482051

20492052
switch (button)
20502053
{
20512054
// Left Button
20522055
case 1:
2053-
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 4), Flags = MouseFlags.Button1Pressed });
2056+
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 6), Flags = MouseFlags.Button1Pressed });
20542057
Assert.True (cm.MenuBar!.IsMenuOpen);
20552058
Application.MainLoop.RunIteration ();
20562059
Assert.False (actionRaised);
2057-
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 4), Flags = MouseFlags.Button1Released });
2060+
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 6), Flags = MouseFlags.Button1Released });
20582061
Assert.True (cm.MenuBar!.IsMenuOpen);
20592062
Application.MainLoop.RunIteration ();
20602063
Assert.False (actionRaised);
2061-
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 4), Flags = MouseFlags.Button1Clicked });
2064+
Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 6), Flags = MouseFlags.Button1Clicked });
20622065
Assert.False (cm.MenuBar!.IsMenuOpen);
20632066
Application.MainLoop.RunIteration ();
20642067
Assert.True (actionRaised);

Tests/UnitTests/Views/MenuBarTests.cs

+20-10
Original file line numberDiff line numberDiff line change
@@ -2518,7 +2518,7 @@ public void MouseEvent_Test ()
25182518
MenuItem miCurrent = null;
25192519
Menu mCurrent = null;
25202520

2521-
var menu = new MenuBar
2521+
var menuBar = new MenuBar
25222522
{
25232523
Menus =
25242524
[
@@ -2533,22 +2533,22 @@ public void MouseEvent_Test ()
25332533
]
25342534
};
25352535

2536-
menu.MenuOpened += (s, e) =>
2536+
menuBar.MenuOpened += (s, e) =>
25372537
{
25382538
miCurrent = e.MenuItem;
2539-
mCurrent = menu.OpenCurrentMenu;
2539+
mCurrent = menuBar.OpenCurrentMenu;
25402540
};
25412541
var top = new Toplevel ();
2542-
top.Add (menu);
2542+
top.Add (menuBar);
25432543
Application.Begin (top);
25442544

25452545
// Click on Edit
25462546
Assert.True (
2547-
menu.NewMouseEvent (
2548-
new () { Position = new (10, 0), Flags = MouseFlags.Button1Pressed, View = menu }
2547+
menuBar.NewMouseEvent (
2548+
new () { Position = new (10, 0), Flags = MouseFlags.Button1Pressed, View = menuBar }
25492549
)
25502550
);
2551-
Assert.True (menu.IsMenuOpen);
2551+
Assert.True (menuBar.IsMenuOpen);
25522552
Assert.Equal ("_Edit", miCurrent.Parent.Title);
25532553
Assert.Equal ("_Copy", miCurrent.Title);
25542554

@@ -2558,7 +2558,7 @@ public void MouseEvent_Test ()
25582558
new () { Position = new (10, 2), Flags = MouseFlags.ReportMousePosition, View = mCurrent }
25592559
)
25602560
);
2561-
Assert.True (menu.IsMenuOpen);
2561+
Assert.True (menuBar.IsMenuOpen);
25622562
Assert.Equal ("_Edit", miCurrent.Parent.Title);
25632563
Assert.Equal ("_Paste", miCurrent.Title);
25642564

@@ -2568,8 +2568,18 @@ public void MouseEvent_Test ()
25682568
new () { ScreenPosition = new (10, i), Flags = MouseFlags.ReportMousePosition }
25692569
);
25702570

2571-
Assert.True (menu.IsMenuOpen);
2572-
Assert.Equal (menu, Application.MouseGrabView);
2571+
Assert.True (menuBar.IsMenuOpen);
2572+
Menu menu = (Menu)top.SubViews.First (v => v is Menu);
2573+
2574+
if (i is < 0 or > 0)
2575+
{
2576+
Assert.Equal (menu, Application.MouseGrabView);
2577+
}
2578+
else
2579+
{
2580+
Assert.Equal (menuBar, Application.MouseGrabView);
2581+
}
2582+
25732583
Assert.Equal ("_Edit", miCurrent.Parent.Title);
25742584

25752585
if (i == 4)

0 commit comments

Comments
 (0)