diff --git a/Terminal.Gui/Application/ApplicationNavigation.cs b/Terminal.Gui/Application/ApplicationNavigation.cs
index 8794dc2f2..fe9c66b3b 100644
--- a/Terminal.Gui/Application/ApplicationNavigation.cs
+++ b/Terminal.Gui/Application/ApplicationNavigation.cs
@@ -7,6 +7,7 @@ namespace Terminal.Gui;
///
public class ApplicationNavigation
{
+
///
/// Initializes a new instance of the class.
///
@@ -15,6 +16,75 @@ public class ApplicationNavigation
// TODO: Move navigation key bindings here from AddApplicationKeyBindings
}
+ private View? _focused = null;
+
+ ///
+ /// Gets the most focused in the application, if there is one.
+ ///
+ public View? GetFocused () { return _focused; }
+
+ ///
+ /// INTERNAL method to record the most focused in the application.
+ ///
+ ///
+ /// Raises .
+ ///
+ internal void SetFocused (View? value)
+ {
+ if (_focused == value)
+ {
+ return;
+ }
+
+ _focused = value;
+
+ FocusedChanged?.Invoke (null, EventArgs.Empty);
+
+ return;
+ }
+
+ ///
+ /// Raised when the most focused in the application has changed.
+ ///
+ public event EventHandler? FocusedChanged;
+
+
+ ///
+ /// Gets whether is in the Subview hierarchy of .
+ ///
+ ///
+ ///
+ ///
+ public static bool IsInHierarchy (View start, View? view)
+ {
+ if (view is null)
+ {
+ return false;
+ }
+
+ if (view == start)
+ {
+ return true;
+ }
+
+ foreach (View subView in start.Subviews)
+ {
+ if (view == subView)
+ {
+ return true;
+ }
+
+ var found = IsInHierarchy (subView, view);
+ if (found)
+ {
+ return found;
+ }
+ }
+
+ return false;
+ }
+
+
///
/// Gets the deepest focused subview of the specified .
///
diff --git a/Terminal.Gui/View/View.Navigation.cs b/Terminal.Gui/View/View.Navigation.cs
index ad33804d2..3874aca49 100644
--- a/Terminal.Gui/View/View.Navigation.cs
+++ b/Terminal.Gui/View/View.Navigation.cs
@@ -72,6 +72,11 @@ public partial class View // Focus and cross-view navigation management (TabStop
{
if (Focused.AdvanceFocus (direction, behavior))
{
+ // TODO: Temporary hack to make Application.Navigation.FocusChanged work
+ if (Focused.Focused is null)
+ {
+ Application.Navigation!.SetFocused (Focused);
+ }
return true;
}
}
@@ -144,6 +149,12 @@ public partial class View // Focus and cross-view navigation management (TabStop
SetFocus (view);
+ // TODO: Temporary hack to make Application.Navigation.FocusChanged work
+ if (view.Focused is null)
+ {
+ Application.Navigation!.SetFocused (view);
+ }
+
return true;
}
@@ -604,6 +615,13 @@ public partial class View // Focus and cross-view navigation management (TabStop
{
// If there is no SuperView, then this is a top-level view
SetFocus (this);
+
+ }
+
+ // TODO: Temporary hack to make Application.Navigation.FocusChanged work
+ if (HasFocus && Focused.Focused is null)
+ {
+ Application.Navigation!.SetFocused (Focused);
}
// TODO: This is a temporary hack to make overlapped non-Toplevels have a zorder. See also: View.OnDrawContent.
diff --git a/UICatalog/Scenarios/AdornmentsEditor.cs b/UICatalog/Scenarios/AdornmentsEditor.cs
index a8595d2dd..472ed4897 100644
--- a/UICatalog/Scenarios/AdornmentsEditor.cs
+++ b/UICatalog/Scenarios/AdornmentsEditor.cs
@@ -34,27 +34,27 @@ public class AdornmentsEditor : View
TabStop = TabBehavior.TabGroup;
- Application.MouseEvent += Application_MouseEvent;
- //ApplicationNavigation.FocusedChanged += ApplicationNavigationOnFocusedChanged;
+ //Application.MouseEvent += Application_MouseEvent;
+ Application.Navigation!.FocusedChanged += ApplicationNavigationOnFocusedChanged;
Initialized += AdornmentsEditor_Initialized;
}
- //private void ApplicationNavigationOnFocusedChanged (object sender, EventArgs e)
- //{
- // if (ApplicationNavigation.IsInHierarchy (this, ApplicationNavigation.Focused))
- // {
- // return;
- // }
+ private void ApplicationNavigationOnFocusedChanged (object sender, EventArgs e)
+ {
+ if (ApplicationNavigation.IsInHierarchy (this, Application.Navigation!.GetFocused ()))
+ {
+ return;
+ }
- // if (ApplicationNavigation.Focused is Adornment adornment)
- // {
- // ViewToEdit = adornment.Parent;
- // }
- // else
- // {
- // ViewToEdit = ApplicationNavigation.Focused;
- // }
- //}
+ if (Application.Navigation!.GetFocused () is Adornment adornment)
+ {
+ ViewToEdit = adornment.Parent;
+ }
+ else
+ {
+ ViewToEdit = Application.Navigation.GetFocused ();
+ }
+ }
///
/// Gets or sets whether the AdornmentsEditor should automatically select the View to edit when the mouse is clicked
@@ -128,7 +128,7 @@ public class AdornmentsEditor : View
_diagPaddingCheckBox.Y = Pos.Bottom (_paddingEditor);
_diagRulerCheckBox = new () { Text = "_Diagnostic Ruler" };
- _diagRulerCheckBox.State = Diagnostics.FastHasFlags(ViewDiagnosticFlags.Ruler) ? CheckState.Checked : CheckState.UnChecked;
+ _diagRulerCheckBox.State = Diagnostics.FastHasFlags (ViewDiagnosticFlags.Ruler) ? CheckState.Checked : CheckState.UnChecked;
_diagRulerCheckBox.Toggle += (s, e) =>
{
@@ -192,7 +192,7 @@ public class AdornmentsEditor : View
_borderEditor.AdornmentToEdit = _viewToEdit?.Border ?? null;
_paddingEditor.AdornmentToEdit = _viewToEdit?.Padding ?? null;
- _lblView.Text = $"{_viewToEdit?.GetType ().Name}: {_viewToEdit?.Id}" ?? string.Empty;
+ _lblView.Text = $"{_viewToEdit?.GetType ().Name}: {_viewToEdit?.Id}" ?? string.Empty;
return;
}
diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs
index 5e0dc2a5c..c179ef012 100644
--- a/UnitTests/UICatalog/ScenarioTests.cs
+++ b/UnitTests/UICatalog/ScenarioTests.cs
@@ -40,6 +40,7 @@ public class ScenarioTests : TestsAllViews
var initialized = false;
var shutdown = false;
object timeout = null;
+ int iterationCount = 0;
Application.InitializedChanged += OnApplicationOnInitializedChanged;
@@ -106,7 +107,7 @@ public class ScenarioTests : TestsAllViews
}
Assert.Fail (
- $"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms. Force quit.");
+ $"'{scenario.GetName ()}' failed to Quit with {Application.QuitKey} after {abortTime}ms and {iterationCount} iterations. Force quit.");
Application.ResetState (true);
@@ -115,6 +116,7 @@ public class ScenarioTests : TestsAllViews
void OnApplicationOnIteration (object s, IterationEventArgs a)
{
+ iterationCount++;
if (Application.IsInitialized)
{
// Press QuitKey