diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs
index 233b0c1fa..5d8cc1fdf 100644
--- a/Terminal.Gui/Core/Application.cs
+++ b/Terminal.Gui/Core/Application.cs
@@ -1053,7 +1053,8 @@ namespace Terminal.Gui {
MdiTop.OnAllChildClosed ();
} else {
SetCurrentAsTop ();
- Current.OnEnter (Current);
+ runState.Toplevel.OnLeave (Current);
+ Current.OnEnter (runState.Toplevel);
}
Refresh ();
}
diff --git a/Terminal.Gui/Core/Border.cs b/Terminal.Gui/Core/Border.cs
index abf4438ce..08e4b614c 100644
--- a/Terminal.Gui/Core/Border.cs
+++ b/Terminal.Gui/Core/Border.cs
@@ -284,7 +284,7 @@ namespace Terminal.Gui {
///
public override void OnCanFocusChanged ()
{
- if (Border.Child != null) {
+ if (Border?.Child != null) {
Border.Child.CanFocus = CanFocus;
}
base.OnCanFocusChanged ();
diff --git a/Terminal.Gui/Core/Toplevel.cs b/Terminal.Gui/Core/Toplevel.cs
index f06345152..04f8995e8 100644
--- a/Terminal.Gui/Core/Toplevel.cs
+++ b/Terminal.Gui/Core/Toplevel.cs
@@ -552,6 +552,7 @@ namespace Terminal.Gui {
///
public override void Add (View view)
{
+ CanFocus = true;
AddMenuStatusBar (view);
base.Add (view);
}
diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs
index ed6439a8b..b2805320b 100644
--- a/Terminal.Gui/Core/View.cs
+++ b/Terminal.Gui/Core/View.cs
@@ -995,9 +995,6 @@ namespace Terminal.Gui {
view.tabIndex = -1;
SetNeedsLayout ();
SetNeedsDisplay ();
- if (subviews.Count < 1) {
- CanFocus = false;
- }
foreach (var v in subviews) {
if (v.Frame.IntersectsWith (touched))
view.SetNeedsDisplay ();
diff --git a/Terminal.Gui/Core/Window.cs b/Terminal.Gui/Core/Window.cs
index 53925f258..febb7517e 100644
--- a/Terminal.Gui/Core/Window.cs
+++ b/Terminal.Gui/Core/Window.cs
@@ -270,9 +270,6 @@ namespace Terminal.Gui {
SetNeedsDisplay ();
contentView.Remove (view);
- if (contentView.InternalSubviews.Count < 1) {
- CanFocus = false;
- }
RemoveMenuStatusBar (view);
if (view != contentView && Focused == null) {
FocusFirst ();
diff --git a/UnitTests/TopLevels/ToplevelTests.cs b/UnitTests/TopLevels/ToplevelTests.cs
index 120ed6b35..89960d5ce 100644
--- a/UnitTests/TopLevels/ToplevelTests.cs
+++ b/UnitTests/TopLevels/ToplevelTests.cs
@@ -1009,7 +1009,98 @@ namespace Terminal.Gui.TopLevelTests {
Application.End (rs);
Assert.True (isEnter);
- Assert.True (isLeave); // Leave event is now also invoked on Application.End allowing preform same output action
+ Assert.False (isLeave); // Leave event cannot be trigger because it v.Enter was performed and v is focused
+ Assert.True (v.HasFocus);
+ }
+
+ [Fact, AutoInitShutdown]
+ public void OnEnter_OnLeave_Triggered_On_Application_Begin_End_With_More_Toplevels ()
+ {
+ var iterations = 0;
+ var steps = new int [5];
+ var isEnterTop = false;
+ var isLeaveTop = false;
+ var vt = new View ();
+ var top = Application.Top;
+ var diag = new Dialog ();
+
+ vt.Enter += (e) => {
+ iterations++;
+ isEnterTop = true;
+ if (iterations == 1) {
+ steps [0] = iterations;
+ Assert.Null (e.View);
+ } else {
+ steps [4] = iterations;
+ Assert.Equal (diag, e.View);
+ }
+ };
+ vt.Leave += (e) => {
+ iterations++;
+ steps [1] = iterations;
+ isLeaveTop = true;
+ Assert.Equal (diag, e.View);
+ };
+ top.Add (vt);
+
+ Assert.False (vt.CanFocus);
+ var exception = Record.Exception (() => top.OnEnter (top));
+ Assert.Null (exception);
+ exception = Record.Exception (() => top.OnLeave (top));
+ Assert.Null (exception);
+
+ vt.CanFocus = true;
+ Application.Begin (top);
+
+ Assert.True (isEnterTop);
+ Assert.False (isLeaveTop);
+
+ isEnterTop = false;
+ var isEnterDiag = false;
+ var isLeaveDiag = false;
+ var vd = new View ();
+ vd.Enter += (e) => {
+ iterations++;
+ steps [2] = iterations;
+ isEnterDiag = true;
+ Assert.Null (e.View);
+ };
+ vd.Leave += (e) => {
+ iterations++;
+ steps [3] = iterations;
+ isLeaveDiag = true;
+ Assert.Equal (top, e.View);
+ };
+ diag.Add (vd);
+
+ Assert.False (vd.CanFocus);
+ exception = Record.Exception (() => diag.OnEnter (diag));
+ Assert.Null (exception);
+ exception = Record.Exception (() => diag.OnLeave (diag));
+ Assert.Null (exception);
+
+ vd.CanFocus = true;
+ var rs = Application.Begin (diag);
+
+ Assert.True (isEnterDiag);
+ Assert.False (isLeaveDiag);
+ Assert.False (isEnterTop);
+ Assert.True (isLeaveTop);
+
+ isEnterDiag = false;
+ isLeaveTop = false;
+ Application.End (rs);
+
+ Assert.False (isEnterDiag);
+ Assert.True (isLeaveDiag);
+ Assert.True (isEnterTop);
+ Assert.False (isLeaveTop); // Leave event cannot be trigger because it v.Enter was performed and v is focused
+ Assert.True (vt.HasFocus);
+ Assert.Equal (1, steps [0]);
+ Assert.Equal (2, steps [1]);
+ Assert.Equal (3, steps [2]);
+ Assert.Equal (4, steps [3]);
+ Assert.Equal (5, steps [^1]);
}
[Fact, AutoInitShutdown]
@@ -1031,5 +1122,22 @@ namespace Terminal.Gui.TopLevelTests {
Application.Driver.GetCursorVisibility (out cursor);
Assert.Equal (CursorVisibility.Invisible, cursor);
}
+
+ [Fact, AutoInitShutdown]
+ public void Activating_MenuBar_By_Alt_Key_Does_Not_Throw ()
+ {
+ var menu = new MenuBar (new MenuBarItem [] {
+ new MenuBarItem ("Child", new MenuItem [] {
+ new MenuItem ("_Create Child", "", null)
+ })
+ });
+ var topChild = new Toplevel ();
+ topChild.Add (menu);
+ Application.Top.Add (topChild);
+ Application.Begin (Application.Top);
+
+ var exception = Record.Exception (() => topChild.ProcessHotKey (new KeyEvent (Key.AltMask, new KeyModifiers { Alt = true })));
+ Assert.Null (exception);
+ }
}
}
\ No newline at end of file