Browse Source

Merge branch 'v2_develop' into v2_2432-DimAuto

Tig 1 year ago
parent
commit
acaa326c51

+ 120 - 6
Terminal.Gui/Application.cs

@@ -1,7 +1,10 @@
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.Diagnostics;
 using System.Globalization;
 using System.Globalization;
 using System.Reflection;
 using System.Reflection;
+using System.Reflection.Metadata.Ecma335;
 using System.Text.Json.Serialization;
 using System.Text.Json.Serialization;
+using static Unix.Terminal.Curses;
 
 
 namespace Terminal.Gui;
 namespace Terminal.Gui;
 
 
@@ -542,8 +545,11 @@ public static partial class Application
             toplevel.OnLoaded ();
             toplevel.OnLoaded ();
             toplevel.SetNeedsDisplay ();
             toplevel.SetNeedsDisplay ();
             toplevel.Draw ();
             toplevel.Draw ();
-            toplevel.PositionCursor ();
-            Driver.Refresh ();
+            Driver.UpdateScreen ();
+            if (PositionCursor (toplevel))
+            {
+                Driver.UpdateCursor ();
+            }
         }
         }
 
 
         NotifyNewRunState?.Invoke (toplevel, new (rs));
         NotifyNewRunState?.Invoke (toplevel, new (rs));
@@ -551,6 +557,100 @@ public static partial class Application
         return rs;
         return rs;
     }
     }
 
 
+    private static CursorVisibility _cachedCursorVisibility;
+
+    /// <summary>
+    /// Calls <see cref="View.PositionCursor"/> on the most focused view in the view starting with <paramref name="view"/>.
+    /// </summary>
+    /// <remarks>
+    /// Does nothing if <paramref name="view"/> is <see langword="null"/> or if the most focused view is not visible or enabled.
+    /// <para>
+    /// If the most focused view is not visible within it's superview, the cursor will be hidden.
+    /// </para>
+    /// </remarks>
+    /// <returns><see langword="true"/> if a view positioned the cursor and the position is visible.</returns>
+    internal static bool PositionCursor (View view)
+    {
+        if (view is null)
+        {
+            return false;
+        }
+
+        // Find the most focused view and position the cursor there.
+        View mostFocused = view.MostFocused;
+
+        if (mostFocused is null)
+        {
+            return false;
+        }
+
+        CursorVisibility cachedCursorVisibility;
+
+        // If the view is not visible or enabled, don't position the cursor
+        if (!mostFocused.Visible || !mostFocused.Enabled)
+        {
+            Driver.GetCursorVisibility (out cachedCursorVisibility);
+
+            if (cachedCursorVisibility != CursorVisibility.Invisible)
+            {
+                _cachedCursorVisibility = cachedCursorVisibility;
+                Driver.SetCursorVisibility (CursorVisibility.Invisible);
+            }
+
+            return false;
+        }
+
+        // If the view is not visible within it's superview, don't position the cursor
+        Rectangle mostFocusedViewport = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = Point.Empty });
+        Rectangle superViewViewport = mostFocused.SuperView?.ViewportToScreen (mostFocused.SuperView.Viewport with { Location = Point.Empty }) ?? Driver.Screen;
+        if (!superViewViewport.IntersectsWith (mostFocusedViewport))
+        {
+            return false;
+        }
+
+        Point? prevCursor = new (Driver.Row, Driver.Col);
+        Point? cursor = mostFocused.PositionCursor ();
+
+        // If the cursor is not in a visible location in the SuperView, hide it
+        if (cursor is { })
+        {
+            // Convert cursor to screen coords
+            cursor = mostFocused.ViewportToScreen (mostFocused.Viewport with { Location = cursor.Value }).Location;
+            if (!superViewViewport.Contains (cursor.Value))
+            {
+                Driver.GetCursorVisibility (out cachedCursorVisibility);
+
+                if (cachedCursorVisibility != CursorVisibility.Invisible)
+                {
+                    _cachedCursorVisibility = cachedCursorVisibility;
+                }
+
+                Driver.SetCursorVisibility (CursorVisibility.Invisible);
+
+                return false;
+            }
+
+            Driver.GetCursorVisibility (out cachedCursorVisibility);
+
+            if (cachedCursorVisibility == CursorVisibility.Invisible)
+            {
+                Driver.SetCursorVisibility (_cachedCursorVisibility);
+            }
+
+            return prevCursor != cursor;
+        }
+
+        Driver.GetCursorVisibility (out cachedCursorVisibility);
+
+        if (cachedCursorVisibility != CursorVisibility.Invisible)
+        {
+            _cachedCursorVisibility = cachedCursorVisibility;
+            Driver.SetCursorVisibility (CursorVisibility.Invisible);
+        }
+
+        return false;
+    }
+
     /// <summary>
     /// <summary>
     ///     Runs the application by creating a <see cref="Toplevel"/> object and calling
     ///     Runs the application by creating a <see cref="Toplevel"/> object and calling
     ///     <see cref="Run(Toplevel, Func{Exception, bool}, ConsoleDriver)"/>.
     ///     <see cref="Run(Toplevel, Func{Exception, bool}, ConsoleDriver)"/>.
@@ -764,7 +864,6 @@ public static partial class Application
             last = v;
             last = v;
         }
         }
 
 
-        last?.PositionCursor ();
         Driver.Refresh ();
         Driver.Refresh ();
     }
     }
 
 
@@ -877,11 +976,21 @@ public static partial class Application
         if (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded || OverlappedChildNeedsDisplay ())
         if (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded || OverlappedChildNeedsDisplay ())
         {
         {
             state.Toplevel.Draw ();
             state.Toplevel.Draw ();
-            state.Toplevel.PositionCursor ();
-            Driver.Refresh ();
+            Driver.UpdateScreen ();
+            //Driver.UpdateCursor ();
         }
         }
-        else
+
+        if (PositionCursor (state.Toplevel))
+        {
+            Driver.UpdateCursor();
+        }
+
+        //        else
         {
         {
+            //if (PositionCursor (state.Toplevel))
+            //{
+            //    Driver.Refresh ();
+            //}
             //Driver.UpdateCursor ();
             //Driver.UpdateCursor ();
         }
         }
 
 
@@ -1315,6 +1424,11 @@ public static partial class Application
             t.LayoutSubviews ();
             t.LayoutSubviews ();
             t.PositionToplevels ();
             t.PositionToplevels ();
             t.OnSizeChanging (new (args.Size));
             t.OnSizeChanging (new (args.Size));
+
+            if (PositionCursor (t))
+            {
+                Driver.UpdateCursor ();
+            }
         }
         }
 
 
         Refresh ();
         Refresh ();

+ 21 - 24
Terminal.Gui/View/ViewSubViews.cs

@@ -494,7 +494,7 @@ public partial class View
         {
         {
             return true;
             return true;
         }
         }
-        
+
         return false;
         return false;
     }
     }
 
 
@@ -512,7 +512,9 @@ public partial class View
             return true;
             return true;
         }
         }
 
 
-        Driver?.SetCursorVisibility (CursorVisibility.Invisible);
+        // BUGBUG: This is a hack to ensure that the cursor is hidden when the view loses focus.
+        // BUGBUG: This is not needed as the minloop will take care of this.
+        //Driver?.SetCursorVisibility (CursorVisibility.Invisible);
 
 
         return false;
         return false;
     }
     }
@@ -857,35 +859,30 @@ public partial class View
     /// a way of hiding the cursor, so it can be distracting to have the cursor left at
     /// a way of hiding the cursor, so it can be distracting to have the cursor left at
     /// the last focused view. Views should make sure that they place the cursor
     /// the last focused view. Views should make sure that they place the cursor
     /// in a visually sensible place.
     /// in a visually sensible place.
-    public virtual void PositionCursor ()
+    /// <returns>Viewport-relative cursor position.</returns>
+    public virtual Point? PositionCursor ()
     {
     {
-        if (!CanBeVisible (this) || !Enabled)
+        if (!IsInitialized)
         {
         {
-            return;
+            return null;
         }
         }
 
 
-        // BUGBUG: v2 - This needs to support Subviews of Adornments too
+        // TODO: v2 - This needs to support Subviews of Adornments too
 
 
-        if (Focused is null && SuperView is { })
-        {
-            SuperView.EnsureFocus ();
-        }
-        else if (Focused is { Visible: true, Enabled: true, Frame: { Width: > 0, Height: > 0 } })
-        {
-            Focused.PositionCursor ();
-        }
-        else if (Focused?.Visible == true && Focused?.Enabled == false)
-        {
-            Focused = null;
-        }
-        else if (CanFocus && HasFocus && Visible && Frame.Width > 0 && Frame.Height > 0)
-        {
-            Move (TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition, 0);
-        }
-        else
+        // By default we will position the cursor at the top left corner of the Viewport.
+        // Overrides should return the position where the cursor has been placed.
+        Point location = Viewport.Location;
+
+        if (CanFocus && HasFocus && ContentSize != Size.Empty)
         {
         {
-            Move (_frame.X, _frame.Y);
+            location.X = TextFormatter.HotKeyPos == -1 ? 0 : TextFormatter.CursorPosition;
+            location.Y = 0;
+            Move (location.X, location.Y);
+            return location;
         }
         }
+
+        return null;
+
     }
     }
 
 
     #endregion Focus
     #endregion Focus

+ 3 - 3
Terminal.Gui/Views/Button.cs

@@ -146,7 +146,7 @@ public class Button : View
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (HotKey.IsValid && Text != "")
         if (HotKey.IsValid && Text != "")
         {
         {
@@ -156,12 +156,12 @@ public class Button : View
                 {
                 {
                     Move (i, 0);
                     Move (i, 0);
 
 
-                    return;
+                    return new (i,0);
                 }
                 }
             }
             }
         }
         }
 
 
-        base.PositionCursor ();
+        return base.PositionCursor ();
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>

+ 1 - 1
Terminal.Gui/Views/CheckBox.cs

@@ -151,7 +151,7 @@ public class CheckBox : View
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor () { Move (0, 0); }
+    public override Point? PositionCursor () { Move (0, 0); return Point.Empty; }
 
 
     /// <summary>Toggled event, raised when the <see cref="CheckBox"/> is toggled.</summary>
     /// <summary>Toggled event, raised when the <see cref="CheckBox"/> is toggled.</summary>
     /// <remarks>
     /// <remarks>

+ 8 - 7
Terminal.Gui/Views/HexView.cs

@@ -547,7 +547,7 @@ public class HexView : View
     public event EventHandler<HexViewEventArgs> PositionChanged;
     public event EventHandler<HexViewEventArgs> PositionChanged;
 
 
     ///<inheritdoc/>
     ///<inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         var delta = (int)(position - displayStart);
         var delta = (int)(position - displayStart);
         int line = delta / bytesPerLine;
         int line = delta / bytesPerLine;
@@ -555,14 +555,15 @@ public class HexView : View
         int block = item / bsize;
         int block = item / bsize;
         int column = item % bsize * 3;
         int column = item % bsize * 3;
 
 
-        if (leftSide)
+        int x = displayWidth + block * 14 + column + (firstNibble ? 0 : 1);
+        int y = line;
+        if (!leftSide)
         {
         {
-            Move (displayWidth + block * 14 + column + (firstNibble ? 0 : 1), line);
-        }
-        else
-        {
-            Move (displayWidth + bytesPerLine / bsize * 14 + item - 1, line);
+            x = displayWidth + bytesPerLine / bsize * 14 + item - 1;
         }
         }
+
+        Move (x, y);
+        return new (x, y);
     }
     }
 
 
     internal void SetDisplayStart (long value)
     internal void SetDisplayStart (long value)

+ 8 - 7
Terminal.Gui/Views/ListView.cs

@@ -781,16 +781,17 @@ public class ListView : View
     public event EventHandler<ListViewItemEventArgs> OpenSelectedItem;
     public event EventHandler<ListViewItemEventArgs> OpenSelectedItem;
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
-        if (_allowsMarking)
-        {
-            Move (0, _selected - Viewport.Y);
-        }
-        else
+        int x = 0;
+        int y = _selected - Viewport.Y;
+        if (!_allowsMarking)
         {
         {
-            Move (Viewport.Width - 1, _selected - Viewport.Y);
+            x = Viewport.Width - 1;
         }
         }
+
+        Move (x, y);
+        return new Point (x, y);
     }
     }
 
 
     /// <summary>This event is invoked when this <see cref="ListView"/> is being drawn before rendering.</summary>
     /// <summary>This event is invoked when this <see cref="ListView"/> is being drawn before rendering.</summary>

+ 5 - 6
Terminal.Gui/Views/Menu/Menu.cs

@@ -946,23 +946,22 @@ internal sealed class Menu : View
         }
         }
     }
     }
 
 
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (_host?.IsMenuOpen != false)
         if (_host?.IsMenuOpen != false)
         {
         {
             if (_barItems.IsTopLevel)
             if (_barItems.IsTopLevel)
             {
             {
-                _host?.PositionCursor ();
+                return _host?.PositionCursor ();
             }
             }
             else
             else
             {
             {
                 Move (2, 1 + _currentChild);
                 Move (2, 1 + _currentChild);
+                return new (2, 1 + _currentChild);
             }
             }
         }
         }
-        else
-        {
-            _host?.PositionCursor ();
-        }
+
+        return _host?.PositionCursor ();
     }
     }
 
 
     public void Run (Action action)
     public void Run (Action action)

+ 3 - 2
Terminal.Gui/Views/Menu/MenuBar.cs

@@ -605,7 +605,7 @@ public class MenuBar : View
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (_selected == -1 && HasFocus && Menus.Length > 0)
         if (_selected == -1 && HasFocus && Menus.Length > 0)
         {
         {
@@ -621,7 +621,7 @@ public class MenuBar : View
                 pos++;
                 pos++;
                 Move (pos + 1, 0);
                 Move (pos + 1, 0);
 
 
-                return;
+                return new (pos +1, 0);
             }
             }
 
 
             pos += _leftPadding
             pos += _leftPadding
@@ -631,6 +631,7 @@ public class MenuBar : View
                           : 0)
                           : 0)
                    + _rightPadding;
                    + _rightPadding;
         }
         }
+        return null;
     }
     }
 
 
     // Activates the menu, handles either first focus, or activating an entry when it was already active
     // Activates the menu, handles either first focus, or activating an entry when it was already active

+ 11 - 3
Terminal.Gui/Views/RadioGroup.cs

@@ -351,19 +351,27 @@ public class RadioGroup : View
     public event EventHandler<OrientationEventArgs> OrientationChanged;
     public event EventHandler<OrientationEventArgs> OrientationChanged;
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
+        int x = 0;
+        int y = 0;
         switch (Orientation)
         switch (Orientation)
         {
         {
             case Orientation.Vertical:
             case Orientation.Vertical:
-                Move (0, _cursor);
+                y = _cursor;
 
 
                 break;
                 break;
             case Orientation.Horizontal:
             case Orientation.Horizontal:
-                Move (_horizontal [_cursor].pos, 0);
+                x = _horizontal [_cursor].pos;
 
 
                 break;
                 break;
+
+            default:
+                return null;
         }
         }
+
+        Move (x, y);
+        return new Point (x, y);
     }
     }
 
 
     /// <summary>Allow to invoke the <see cref="SelectedItemChanged"/> after their creation.</summary>
     /// <summary>Allow to invoke the <see cref="SelectedItemChanged"/> after their creation.</summary>

+ 3 - 5
Terminal.Gui/Views/ScrollView.cs

@@ -455,16 +455,14 @@ public class ScrollView : View
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (InternalSubviews.Count == 0)
         if (InternalSubviews.Count == 0)
         {
         {
             Move (0, 0);
             Move (0, 0);
+            return Point.Empty;
         }
         }
-        else
-        {
-            base.PositionCursor ();
-        }
+        return base.PositionCursor ();
     }
     }
 
 
     /// <summary>Removes the view from the scrollview.</summary>
     /// <summary>Removes the view from the scrollview.</summary>

+ 4 - 1
Terminal.Gui/Views/Slider.cs

@@ -983,7 +983,7 @@ public class Slider<T> : View
     #region Cursor and Drawing
     #region Cursor and Drawing
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         //base.PositionCursor ();
         //base.PositionCursor ();
 
 
@@ -1001,8 +1001,11 @@ public class Slider<T> : View
             if (IsInitialized && Viewport.Contains (position.x, position.y))
             if (IsInitialized && Viewport.Contains (position.x, position.y))
             {
             {
                 Move (position.x, position.y);
                 Move (position.x, position.y);
+
+                return new (position.x, position.x);
             }
             }
         }
         }
+        return null;
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>

+ 5 - 4
Terminal.Gui/Views/TableView/TableView.cs

@@ -1017,13 +1017,11 @@ public class TableView : View
     ///     Positions the cursor in the area of the screen in which the start of the active cell is rendered.  Calls base
     ///     Positions the cursor in the area of the screen in which the start of the active cell is rendered.  Calls base
     ///     implementation if active cell is not visible due to scrolling or table is loaded etc
     ///     implementation if active cell is not visible due to scrolling or table is loaded etc
     /// </summary>
     /// </summary>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (TableIsNullOrInvisible ())
         if (TableIsNullOrInvisible ())
         {
         {
-            base.PositionCursor ();
-
-            return;
+            return base.PositionCursor ();
         }
         }
 
 
         Point? screenPoint = CellToScreen (SelectedColumn, SelectedRow);
         Point? screenPoint = CellToScreen (SelectedColumn, SelectedRow);
@@ -1031,7 +1029,10 @@ public class TableView : View
         if (screenPoint is { })
         if (screenPoint is { })
         {
         {
             Move (screenPoint.Value.X, screenPoint.Value.Y);
             Move (screenPoint.Value.X, screenPoint.Value.Y);
+            return screenPoint;
         }
         }
+
+        return null;
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 4 - 85
Terminal.Gui/Views/TextField.cs

@@ -9,10 +9,8 @@ namespace Terminal.Gui;
 public class TextField : View
 public class TextField : View
 {
 {
     private readonly HistoryText _historyText;
     private readonly HistoryText _historyText;
-    private readonly CursorVisibility _savedCursorVisibility;
     private CultureInfo _currentCulture;
     private CultureInfo _currentCulture;
     private int _cursorPosition;
     private int _cursorPosition;
-    private CursorVisibility _desiredCursorVisibility;
     private bool _isButtonPressed;
     private bool _isButtonPressed;
     private bool _isButtonReleased;
     private bool _isButtonReleased;
     private bool _isDrawing;
     private bool _isDrawing;
@@ -21,7 +19,6 @@ public class TextField : View
     private string _selectedText;
     private string _selectedText;
     private int _start;
     private int _start;
     private List<Rune> _text;
     private List<Rune> _text;
-    private CursorVisibility _visibility;
 
 
     /// <summary>
     /// <summary>
     ///     Initializes a new instance of the <see cref="TextField"/> class using <see cref="LayoutStyle.Computed"/>
     ///     Initializes a new instance of the <see cref="TextField"/> class using <see cref="LayoutStyle.Computed"/>
@@ -30,7 +27,6 @@ public class TextField : View
     public TextField ()
     public TextField ()
     {
     {
         _historyText = new HistoryText ();
         _historyText = new HistoryText ();
-        _desiredCursorVisibility = CursorVisibility.Default;
         _isButtonReleased = true;
         _isButtonReleased = true;
         _selectedStart = -1;
         _selectedStart = -1;
         _text = new List<Rune> ();
         _text = new List<Rune> ();
@@ -42,7 +38,6 @@ public class TextField : View
         CanFocus = true;
         CanFocus = true;
         Used = true;
         Used = true;
         WantMousePositionReports = true;
         WantMousePositionReports = true;
-        _savedCursorVisibility = _desiredCursorVisibility;
 
 
         _historyText.ChangeText += HistoryText_ChangeText;
         _historyText.ChangeText += HistoryText_ChangeText;
 
 
@@ -469,21 +464,6 @@ public class TextField : View
         }
         }
     }
     }
 
 
-    /// <summary>Get / Set the wished cursor when the field is focused</summary>
-    public CursorVisibility DesiredCursorVisibility
-    {
-        get => _desiredCursorVisibility;
-        set
-        {
-            if ((_desiredCursorVisibility != value || _visibility != value) && HasFocus)
-            {
-                Application.Driver.SetCursorVisibility (value);
-            }
-
-            _desiredCursorVisibility = _visibility = value;
-        }
-    }
-
     /// <summary>
     /// <summary>
     ///     Indicates whatever the text has history changes or not. <see langword="true"/> if the text has history changes
     ///     Indicates whatever the text has history changes or not. <see langword="true"/> if the text has history changes
     ///     <see langword="false"/> otherwise.
     ///     <see langword="false"/> otherwise.
@@ -1060,7 +1040,7 @@ public class TextField : View
     {
     {
         if (IsInitialized)
         if (IsInitialized)
         {
         {
-            Application.Driver.SetCursorVisibility (DesiredCursorVisibility);
+            Application.Driver.SetCursorVisibility (CursorVisibility.Default);
         }
         }
 
 
         return base.OnEnter (view);
         return base.OnEnter (view);
@@ -1172,13 +1152,8 @@ public class TextField : View
     }
     }
 
 
     /// <summary>Sets the cursor position.</summary>
     /// <summary>Sets the cursor position.</summary>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
-        if (!IsInitialized)
-        {
-            return;
-        }
-
         ProcessAutocomplete ();
         ProcessAutocomplete ();
 
 
         var col = 0;
         var col = 0;
@@ -1195,31 +1170,8 @@ public class TextField : View
         }
         }
 
 
         int pos = _cursorPosition - ScrollOffset + Math.Min (Frame.X, 0);
         int pos = _cursorPosition - ScrollOffset + Math.Min (Frame.X, 0);
-        int offB = OffSetBackground ();
-        Rectangle containerFrame = SuperView?.ViewportToScreen (SuperView.Viewport) ?? default (Rectangle);
-        Rectangle thisFrame = ViewportToScreen (Viewport);
-
-        if (pos > -1
-            && col >= pos
-            && pos < Frame.Width + offB
-            && containerFrame.IntersectsWith (thisFrame))
-        {
-            RestoreCursorVisibility ();
-            Move (col, 0);
-        }
-        else
-        {
-            HideCursorVisibility ();
-
-            if (pos < 0)
-            {
-                Move (pos, 0);
-            }
-            else
-            {
-                Move (pos - offB, 0);
-            }
-        }
+        Move (pos, 0);
+        return new Point (pos, 0);
     }
     }
 
 
     /// <summary>Redoes the latest changes.</summary>
     /// <summary>Redoes the latest changes.</summary>
@@ -1231,21 +1183,6 @@ public class TextField : View
         }
         }
 
 
         _historyText.Redo ();
         _historyText.Redo ();
-
-        //if (string.IsNullOrEmpty (Clipboard.Contents))
-        //	return true;
-        //var clip = TextModel.ToRunes (Clipboard.Contents);
-        //if (clip is null)
-        //	return true;
-
-        //if (point == text.Count) {
-        //	point = text.Count;
-        //	SetText(text.Concat(clip).ToList());
-        //} else {
-        //	point += clip.Count;
-        //	SetText(text.GetRange(0, oldCursorPos).Concat(clip).Concat(text.GetRange(oldCursorPos, text.Count - oldCursorPos)));
-        //}
-        //Adjust ();
     }
     }
 
 
     /// <summary>Selects all text.</summary>
     /// <summary>Selects all text.</summary>
@@ -1465,14 +1402,6 @@ public class TextField : View
         return new Attribute (cs.Disabled.Foreground, cs.Focus.Background);
         return new Attribute (cs.Disabled.Foreground, cs.Focus.Background);
     }
     }
 
 
-    private void HideCursorVisibility ()
-    {
-        if (_desiredCursorVisibility != CursorVisibility.Invisible)
-        {
-            DesiredCursorVisibility = CursorVisibility.Invisible;
-        }
-    }
-
     private void HistoryText_ChangeText (object sender, HistoryText.HistoryTextItem obj)
     private void HistoryText_ChangeText (object sender, HistoryText.HistoryTextItem obj)
     {
     {
         if (obj is null)
         if (obj is null)
@@ -1886,16 +1815,6 @@ public class TextField : View
         Driver.AddStr (render);
         Driver.AddStr (render);
     }
     }
 
 
-    private void RestoreCursorVisibility ()
-    {
-        Application.Driver.GetCursorVisibility (out _visibility);
-
-        if (_desiredCursorVisibility != _savedCursorVisibility || _visibility != _savedCursorVisibility)
-        {
-            DesiredCursorVisibility = _savedCursorVisibility;
-        }
-    }
-
     private void SetClipboard (IEnumerable<Rune> text)
     private void SetClipboard (IEnumerable<Rune> text)
     {
     {
         if (!Secret)
         if (!Secret)

+ 3 - 3
Terminal.Gui/Views/TextValidateField.cs

@@ -640,7 +640,7 @@ namespace Terminal.Gui
         }
         }
 
 
         /// <inheritdoc/>
         /// <inheritdoc/>
-        public override void PositionCursor ()
+        public override Point? PositionCursor ()
         {
         {
             (int left, _) = GetMargins (Viewport.Width);
             (int left, _) = GetMargins (Viewport.Width);
 
 
@@ -652,13 +652,12 @@ namespace Terminal.Gui
             if (_provider?.Fixed == false && TextAlignment == TextAlignment.Right)
             if (_provider?.Fixed == false && TextAlignment == TextAlignment.Right)
             {
             {
                 curPos = _cursorPosition + left - 1;
                 curPos = _cursorPosition + left - 1;
-                Move (curPos, 0);
             }
             }
             else
             else
             {
             {
                 curPos = _cursorPosition + left;
                 curPos = _cursorPosition + left;
-                Move (curPos, 0);
             }
             }
+            Move (curPos, 0);
 
 
             if (curPos < 0 || curPos >= Viewport.Width)
             if (curPos < 0 || curPos >= Viewport.Width)
             {
             {
@@ -668,6 +667,7 @@ namespace Terminal.Gui
             {
             {
                 Application.Driver.SetCursorVisibility (CursorVisibility.Default);
                 Application.Driver.SetCursorVisibility (CursorVisibility.Default);
             }
             }
+            return new (curPos, 0);
         }
         }
 
 
         /// <summary>Delete char at cursor position - 1, moving the cursor.</summary>
         /// <summary>Delete char at cursor position - 1, moving the cursor.</summary>

+ 178 - 206
Terminal.Gui/Views/TextView.cs

@@ -67,7 +67,7 @@ internal class TextModel
         }
         }
 
 
         FilePath = null;
         FilePath = null;
-        _lines = new List<List<RuneCell>> ();
+        _lines = new ();
 
 
         return true;
         return true;
     }
     }
@@ -89,7 +89,7 @@ internal class TextModel
             return _lines [Count - 1];
             return _lines [Count - 1];
         }
         }
 
 
-        _lines.Add (new List<RuneCell> ());
+        _lines.Add (new ());
 
 
         return _lines [0];
         return _lines [0];
     }
     }
@@ -153,7 +153,7 @@ internal class TextModel
             throw new ArgumentNullException (nameof (input));
             throw new ArgumentNullException (nameof (input));
         }
         }
 
 
-        _lines = new List<List<RuneCell>> ();
+        _lines = new ();
         var buff = new BufferedStream (input);
         var buff = new BufferedStream (input);
         int v;
         int v;
         List<byte> line = new ();
         List<byte> line = new ();
@@ -215,7 +215,7 @@ internal class TextModel
     {
     {
         if (_lines.Count > 0 && pos < _lines.Count)
         if (_lines.Count > 0 && pos < _lines.Count)
         {
         {
-            _lines [pos] = new List<RuneCell> (runes);
+            _lines [pos] = new (runes);
         }
         }
         else if (_lines.Count == 0 || (_lines.Count > 0 && pos >= _lines.Count))
         else if (_lines.Count == 0 || (_lines.Count > 0 && pos >= _lines.Count))
         {
         {
@@ -243,7 +243,7 @@ internal class TextModel
 
 
         foreach (Rune rune in str.EnumerateRunes ())
         foreach (Rune rune in str.EnumerateRunes ())
         {
         {
-            cells.Add (new RuneCell { Rune = rune, ColorScheme = colorScheme });
+            cells.Add (new() { Rune = rune, ColorScheme = colorScheme });
         }
         }
 
 
         return cells;
         return cells;
@@ -759,7 +759,7 @@ internal class TextModel
                                                   _lines.Count - 1,
                                                   _lines.Count - 1,
                                                   matchCase,
                                                   matchCase,
                                                   matchWholeWord,
                                                   matchWholeWord,
-                                                  new Point (_lines [_lines.Count - 1].Count, _lines.Count)
+                                                  new (_lines [_lines.Count - 1].Count, _lines.Count)
                                                  );
                                                  );
         }
         }
 
 
@@ -850,7 +850,7 @@ internal class TextModel
                     _lines [i] = ToRuneCellList (ReplaceText (x, textToReplace!, matchText, col));
                     _lines [i] = ToRuneCellList (ReplaceText (x, textToReplace!, matchText, col));
                     x = _lines [i];
                     x = _lines [i];
                     txt = GetText (x);
                     txt = GetText (x);
-                    pos = new Point (col, i);
+                    pos = new (col, i);
                     col += textToReplace!.Length - matchText.Length;
                     col += textToReplace!.Length - matchText.Length;
                 }
                 }
 
 
@@ -906,7 +906,7 @@ internal class TextModel
 
 
         foreach (Rune rune in str.ToRunes ())
         foreach (Rune rune in str.ToRunes ())
         {
         {
-            cells.Add (new RuneCell { Rune = rune, ColorScheme = colorScheme });
+            cells.Add (new() { Rune = rune, ColorScheme = colorScheme });
         }
         }
 
 
         return cells;
         return cells;
@@ -918,7 +918,7 @@ internal class TextModel
 
 
         foreach (Rune rune in runes)
         foreach (Rune rune in runes)
         {
         {
-            cells.Add (new RuneCell { Rune = rune, ColorScheme = colorScheme });
+            cells.Add (new() { Rune = rune, ColorScheme = colorScheme });
         }
         }
 
 
         return cells;
         return cells;
@@ -981,7 +981,7 @@ internal class TextModel
 
 
             if (col > -1 && ((i == start.Y && col >= start.X) || i > start.Y) && txt.Contains (matchText))
             if (col > -1 && ((i == start.Y && col >= start.X) || i > start.Y) && txt.Contains (matchText))
             {
             {
-                return (new Point (col, i), true);
+                return (new (col, i), true);
             }
             }
 
 
             if (col == -1 && start.X > 0)
             if (col == -1 && start.X > 0)
@@ -1026,7 +1026,7 @@ internal class TextModel
 
 
             if (col > -1 && ((i <= linesCount && col <= start.X) || i < start.Y) && txt.Contains (matchText))
             if (col > -1 && ((i <= linesCount && col <= start.X) || i < start.Y) && txt.Contains (matchText))
             {
             {
-                return (new Point (col, i), true);
+                return (new (col, i), true);
             }
             }
         }
         }
 
 
@@ -1292,7 +1292,7 @@ internal partial class HistoryText
                                           );
                                           );
         }
         }
 
 
-        _historyTextItems.Add (new HistoryTextItem (lines, curPos, lineStatus));
+        _historyTextItems.Add (new (lines, curPos, lineStatus));
         _idxHistoryText++;
         _idxHistoryText++;
     }
     }
 
 
@@ -1370,7 +1370,7 @@ internal partial class HistoryText
                     _idxHistoryText--;
                     _idxHistoryText--;
                 }
                 }
 
 
-                historyTextItem = new HistoryTextItem (_historyTextItems [_idxHistoryText]);
+                historyTextItem = new (_historyTextItems [_idxHistoryText]);
                 historyTextItem.IsUndoing = true;
                 historyTextItem.IsUndoing = true;
                 historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
                 historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
             }
             }
@@ -1378,7 +1378,7 @@ internal partial class HistoryText
             if (historyTextItem.LineStatus == LineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Added)
             if (historyTextItem.LineStatus == LineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Added)
             {
             {
                 historyTextItem.RemovedOnAdded =
                 historyTextItem.RemovedOnAdded =
-                    new HistoryTextItem (_historyTextItems [_idxHistoryText + 1]);
+                    new (_historyTextItems [_idxHistoryText + 1]);
             }
             }
 
 
             if ((historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Original)
             if ((historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Original)
@@ -1390,7 +1390,7 @@ internal partial class HistoryText
                     && historyTextItem.CursorPosition == _historyTextItems [_idxHistoryText - 1].CursorPosition)
                     && historyTextItem.CursorPosition == _historyTextItems [_idxHistoryText - 1].CursorPosition)
                 {
                 {
                     historyTextItem.Lines [0] =
                     historyTextItem.Lines [0] =
-                        new List<RuneCell> (_historyTextItems [_idxHistoryText - 1].Lines [0]);
+                        new (_historyTextItems [_idxHistoryText - 1].Lines [0]);
                 }
                 }
 
 
                 if (historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Removed)
                 if (historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Removed)
@@ -1425,7 +1425,7 @@ internal partial class HistoryText
                     || _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Removed))
                     || _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Removed))
             {
             {
                 _idxHistoryText++;
                 _idxHistoryText++;
-                historyTextItem = new HistoryTextItem (_historyTextItems [_idxHistoryText]);
+                historyTextItem = new (_historyTextItems [_idxHistoryText]);
                 historyTextItem.IsUndoing = false;
                 historyTextItem.IsUndoing = false;
                 historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
                 historyTextItem.FinalCursorPosition = historyTextItem.CursorPosition;
             }
             }
@@ -1433,7 +1433,7 @@ internal partial class HistoryText
             if (historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Removed)
             if (historyTextItem.LineStatus == LineStatus.Added && _historyTextItems [_idxHistoryText - 1].LineStatus == LineStatus.Removed)
             {
             {
                 historyTextItem.RemovedOnAdded =
                 historyTextItem.RemovedOnAdded =
-                    new HistoryTextItem (_historyTextItems [_idxHistoryText - 1]);
+                    new (_historyTextItems [_idxHistoryText - 1]);
             }
             }
 
 
             if ((historyTextItem.LineStatus == LineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Replaced)
             if ((historyTextItem.LineStatus == LineStatus.Removed && _historyTextItems [_idxHistoryText + 1].LineStatus == LineStatus.Replaced)
@@ -1445,7 +1445,7 @@ internal partial class HistoryText
                                        .SequenceEqual (_historyTextItems [_idxHistoryText + 1].Lines [0]))
                                        .SequenceEqual (_historyTextItems [_idxHistoryText + 1].Lines [0]))
                 {
                 {
                     historyTextItem.Lines [0] =
                     historyTextItem.Lines [0] =
-                        new List<RuneCell> (_historyTextItems [_idxHistoryText + 1].Lines [0]);
+                        new (_historyTextItems [_idxHistoryText + 1].Lines [0]);
                 }
                 }
 
 
                 historyTextItem.FinalCursorPosition =
                 historyTextItem.FinalCursorPosition =
@@ -1962,15 +1962,14 @@ public class TextView : View
     private bool _copyWithoutSelection;
     private bool _copyWithoutSelection;
     private string? _currentCaller;
     private string? _currentCaller;
     private CultureInfo? _currentCulture;
     private CultureInfo? _currentCulture;
-    private CursorVisibility _desiredCursorVisibility = CursorVisibility.Default;
     private bool _isButtonShift;
     private bool _isButtonShift;
+    private bool _isButtonReleased;
     private bool _isDrawing;
     private bool _isDrawing;
     private bool _isReadOnly;
     private bool _isReadOnly;
     private bool _lastWasKill;
     private bool _lastWasKill;
     private int _leftColumn;
     private int _leftColumn;
     private TextModel _model = new ();
     private TextModel _model = new ();
     private bool _multiline = true;
     private bool _multiline = true;
-    private CursorVisibility _savedCursorVisibility;
     private Dim? _savedHeight;
     private Dim? _savedHeight;
     private int _selectionStartColumn, _selectionStartRow;
     private int _selectionStartColumn, _selectionStartRow;
     private bool _shiftSelecting;
     private bool _shiftSelecting;
@@ -1980,6 +1979,10 @@ public class TextView : View
     private WordWrapManager? _wrapManager;
     private WordWrapManager? _wrapManager;
     private bool _wrapNeeded;
     private bool _wrapNeeded;
 
 
+    /// <summary>Get or sets the cursor to be used when the text view has focus.</summary>
+
+    public CursorVisibility DesiredCursorVisibility { get; set; } = CursorVisibility.Default;
+
     /// <summary>
     /// <summary>
     ///     Initializes a <see cref="TextView"/> on the specified area, with dimensions controlled with the X, Y, Width
     ///     Initializes a <see cref="TextView"/> on the specified area, with dimensions controlled with the X, Y, Width
     ///     and Height properties.
     ///     and Height properties.
@@ -2398,10 +2401,10 @@ public class TextView : View
                     Command.ShowContextMenu,
                     Command.ShowContextMenu,
                     () =>
                     () =>
                     {
                     {
-                        ContextMenu!.Position = new Point (
-                                                           CursorPosition.X - _leftColumn + 2,
-                                                           CursorPosition.Y - _topRow + 2
-                                                          );
+                        ContextMenu!.Position = new (
+                                                     CursorPosition.X - _leftColumn + 2,
+                                                     CursorPosition.Y - _topRow + 2
+                                                    );
                         ShowContextMenu ();
                         ShowContextMenu ();
 
 
                         return true;
                         return true;
@@ -2509,7 +2512,7 @@ public class TextView : View
 
 
         _currentCulture = Thread.CurrentThread.CurrentUICulture;
         _currentCulture = Thread.CurrentThread.CurrentUICulture;
 
 
-        ContextMenu = new ContextMenu { MenuItems = BuildContextMenuBarItem () };
+        ContextMenu = new() { MenuItems = BuildContextMenuBarItem () };
         ContextMenu.KeyChanged += ContextMenu_KeyChanged!;
         ContextMenu.KeyChanged += ContextMenu_KeyChanged!;
 
 
         KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.ShowContextMenu);
         KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.ShowContextMenu);
@@ -2626,21 +2629,6 @@ public class TextView : View
         }
         }
     }
     }
 
 
-    /// <summary>Get / Set the wished cursor when the field is focused</summary>
-    public CursorVisibility DesiredCursorVisibility
-    {
-        get => _desiredCursorVisibility;
-        set
-        {
-            if (HasFocus)
-            {
-                Application.Driver.SetCursorVisibility (value);
-            }
-
-            _desiredCursorVisibility = value;
-            SetNeedsDisplay ();
-        }
-    }
 
 
     /// <summary>
     /// <summary>
     ///     Indicates whatever the text has history changes or not. <see langword="true"/> if the text has history changes
     ///     Indicates whatever the text has history changes or not. <see langword="true"/> if the text has history changes
@@ -2862,17 +2850,17 @@ public class TextView : View
         }
         }
         set
         set
         {
         {
-            var old = Text;
+            string old = Text;
             ResetPosition ();
             ResetPosition ();
             _model.LoadString (value);
             _model.LoadString (value);
 
 
             if (_wordWrap)
             if (_wordWrap)
             {
             {
-                _wrapManager = new WordWrapManager (_model);
+                _wrapManager = new (_model);
                 _model = _wrapManager.WrapModel (_frameWidth, out _, out _, out _, out _);
                 _model = _wrapManager.WrapModel (_frameWidth, out _, out _, out _, out _);
             }
             }
 
 
-            OnTextChanged (old,Text);
+            OnTextChanged (old, Text);
             SetNeedsDisplay ();
             SetNeedsDisplay ();
 
 
             _historyText.Clear (Text);
             _historyText.Clear (Text);
@@ -2913,7 +2901,7 @@ public class TextView : View
 
 
             if (_wordWrap)
             if (_wordWrap)
             {
             {
-                _wrapManager = new WordWrapManager (_model);
+                _wrapManager = new (_model);
                 _model = _wrapManager.WrapModel (_frameWidth, out _, out _, out _, out _);
                 _model = _wrapManager.WrapModel (_frameWidth, out _, out _, out _, out _);
             }
             }
             else if (!_wordWrap && _wrapManager is { })
             else if (!_wordWrap && _wrapManager is { })
@@ -2982,7 +2970,7 @@ public class TextView : View
             ClearRegion ();
             ClearRegion ();
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (GetCurrentLine ()) },
+                              new() { new (GetCurrentLine ()) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -3021,14 +3009,14 @@ public class TextView : View
 
 
         if (Selecting)
         if (Selecting)
         {
         {
-            _historyText.Add (new List<List<RuneCell>> { new (GetCurrentLine ()) }, CursorPosition);
+            _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition);
 
 
             ClearSelectedRegion ();
             ClearSelectedRegion ();
 
 
             List<RuneCell> currentLine = GetCurrentLine ();
             List<RuneCell> currentLine = GetCurrentLine ();
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (currentLine) },
+                              new() { new (currentLine) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -3065,14 +3053,14 @@ public class TextView : View
 
 
         if (Selecting)
         if (Selecting)
         {
         {
-            _historyText.Add (new List<List<RuneCell>> { new (GetCurrentLine ()) }, CursorPosition);
+            _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition);
 
 
             ClearSelectedRegion ();
             ClearSelectedRegion ();
 
 
             List<RuneCell> currentLine = GetCurrentLine ();
             List<RuneCell> currentLine = GetCurrentLine ();
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (currentLine) },
+                              new() { new (currentLine) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -3204,7 +3192,7 @@ public class TextView : View
 
 
         if (ColorScheme is null)
         if (ColorScheme is null)
         {
         {
-            cs = new ColorScheme ();
+            cs = new ();
         }
         }
 
 
         return Enabled ? cs.Focus : cs.Disabled;
         return Enabled ? cs.Focus : cs.Disabled;
@@ -3223,7 +3211,7 @@ public class TextView : View
 
 
             try
             try
             {
             {
-                key = new Key (ch);
+                key = new (ch);
             }
             }
             catch (Exception)
             catch (Exception)
             {
             {
@@ -3312,7 +3300,7 @@ public class TextView : View
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent ev)
+    protected internal override bool OnMouseEvent (MouseEvent ev)
     {
     {
         if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked)
         if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked)
             && !ev.Flags.HasFlag (MouseFlags.Button1Pressed)
             && !ev.Flags.HasFlag (MouseFlags.Button1Pressed)
@@ -3349,6 +3337,13 @@ public class TextView : View
 
 
         if (ev.Flags == MouseFlags.Button1Clicked)
         if (ev.Flags == MouseFlags.Button1Clicked)
         {
         {
+            if (_isButtonReleased)
+            {
+                _isButtonReleased = false;
+
+                return true;
+            }
+
             if (_shiftSelecting && !_isButtonShift)
             if (_shiftSelecting && !_isButtonShift)
             {
             {
                 StopSelecting ();
                 StopSelecting ();
@@ -3476,6 +3471,7 @@ public class TextView : View
         }
         }
         else if (ev.Flags.HasFlag (MouseFlags.Button1Released))
         else if (ev.Flags.HasFlag (MouseFlags.Button1Released))
         {
         {
+            _isButtonReleased = true;
             Application.UngrabMouse ();
             Application.UngrabMouse ();
         }
         }
         else if (ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
         else if (ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked))
@@ -3544,7 +3540,7 @@ public class TextView : View
         }
         }
         else if (ev.Flags == ContextMenu!.MouseFlags)
         else if (ev.Flags == ContextMenu!.MouseFlags)
         {
         {
-            ContextMenu.Position = new Point (ev.X + 2, ev.Y + 2);
+            ContextMenu.Position = new (ev.X + 2, ev.Y + 2);
             ShowContextMenu ();
             ShowContextMenu ();
         }
         }
 
 
@@ -3579,7 +3575,7 @@ public class TextView : View
     /// </summary>
     /// </summary>
     public virtual void OnContentsChanged ()
     public virtual void OnContentsChanged ()
     {
     {
-        ContentsChanged?.Invoke (this, new ContentsChangedEventArgs (CurrentRow, CurrentColumn));
+        ContentsChanged?.Invoke (this, new (CurrentRow, CurrentColumn));
 
 
         ProcessInheritsPreviousColorScheme (CurrentRow, CurrentColumn);
         ProcessInheritsPreviousColorScheme (CurrentRow, CurrentColumn);
         ProcessAutocomplete ();
         ProcessAutocomplete ();
@@ -3762,7 +3758,7 @@ public class TextView : View
             col = _wrapManager.GetModelColFromWrappedLines (CurrentRow, CurrentColumn);
             col = _wrapManager.GetModelColFromWrappedLines (CurrentRow, CurrentColumn);
         }
         }
 
 
-        UnwrappedCursorPosition?.Invoke (this, new PointEventArgs (new Point ((int)col, (int)row)));
+        UnwrappedCursorPosition?.Invoke (this, new (new ((int)col, (int)row)));
     }
     }
 
 
     /// <summary>Paste the clipboard contents into the current selected position.</summary>
     /// <summary>Paste the clipboard contents into the current selected position.</summary>
@@ -3778,15 +3774,15 @@ public class TextView : View
 
 
         if (_copyWithoutSelection && contents.FirstOrDefault (x => x == '\n' || x == '\r') == 0)
         if (_copyWithoutSelection && contents.FirstOrDefault (x => x == '\n' || x == '\r') == 0)
         {
         {
-            List<RuneCell> runeList = contents is null ? new List<RuneCell> () : TextModel.ToRuneCellList (contents);
+            List<RuneCell> runeList = contents is null ? new () : TextModel.ToRuneCellList (contents);
             List<RuneCell> currentLine = GetCurrentLine ();
             List<RuneCell> currentLine = GetCurrentLine ();
 
 
-            _historyText.Add (new List<List<RuneCell>> { new (currentLine) }, CursorPosition);
+            _historyText.Add (new() { new (currentLine) }, CursorPosition);
 
 
-            List<List<RuneCell>> addedLine = new () { new List<RuneCell> (currentLine), runeList };
+            List<List<RuneCell>> addedLine = new () { new (currentLine), runeList };
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> (addedLine),
+                              new (addedLine),
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Added
                               HistoryText.LineStatus.Added
                              );
                              );
@@ -3795,7 +3791,7 @@ public class TextView : View
             CurrentRow++;
             CurrentRow++;
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (GetCurrentLine ()) },
+                              new() { new (GetCurrentLine ()) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -3816,7 +3812,7 @@ public class TextView : View
             if (Selecting)
             if (Selecting)
             {
             {
                 _historyText.ReplaceLast (
                 _historyText.ReplaceLast (
-                                          new List<List<RuneCell>> { new (GetCurrentLine ()) },
+                                          new() { new (GetCurrentLine ()) },
                                           CursorPosition,
                                           CursorPosition,
                                           HistoryText.LineStatus.Original
                                           HistoryText.LineStatus.Original
                                          );
                                          );
@@ -3831,13 +3827,13 @@ public class TextView : View
     }
     }
 
 
     /// <summary>Positions the cursor on the current row and column</summary>
     /// <summary>Positions the cursor on the current row and column</summary>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         ProcessAutocomplete ();
         ProcessAutocomplete ();
 
 
         if (!CanFocus || !Enabled || Application.Driver is null)
         if (!CanFocus || !Enabled || Application.Driver is null)
         {
         {
-            return;
+            return null;
         }
         }
 
 
         if (Selecting)
         if (Selecting)
@@ -3882,13 +3878,11 @@ public class TextView : View
 
 
         if (posX > -1 && col >= posX && posX < Frame.Width - RightOffset && _topRow <= CurrentRow && posY < Frame.Height - BottomOffset)
         if (posX > -1 && col >= posX && posX < Frame.Width - RightOffset && _topRow <= CurrentRow && posY < Frame.Height - BottomOffset)
         {
         {
-            ResetCursorVisibility ();
             Move (col, CurrentRow - _topRow);
             Move (col, CurrentRow - _topRow);
+            return new (col, CurrentRow - _topRow);
         }
         }
-        else
-        {
-            SaveCursorVisibility ();
-        }
+
+        return null;
     }
     }
 
 
     /// <summary>Redoes the latest changes.</summary>
     /// <summary>Redoes the latest changes.</summary>
@@ -4042,11 +4036,11 @@ public class TextView : View
 
 
         if (colorScheme!.Disabled.Foreground == colorScheme.Focus.Background)
         if (colorScheme!.Disabled.Foreground == colorScheme.Focus.Background)
         {
         {
-            attribute = new Attribute (colorScheme.Focus.Foreground, colorScheme.Focus.Background);
+            attribute = new (colorScheme.Focus.Foreground, colorScheme.Focus.Background);
         }
         }
         else
         else
         {
         {
-            attribute = new Attribute (colorScheme.Disabled.Foreground, colorScheme.Focus.Background);
+            attribute = new (colorScheme.Disabled.Foreground, colorScheme.Focus.Background);
         }
         }
 
 
         Driver.SetAttribute (attribute);
         Driver.SetAttribute (attribute);
@@ -4072,16 +4066,16 @@ public class TextView : View
             ColorScheme? colorScheme = line [idxCol].ColorScheme;
             ColorScheme? colorScheme = line [idxCol].ColorScheme;
 
 
             Driver.SetAttribute (
             Driver.SetAttribute (
-                                 new Attribute (colorScheme!.Focus.Background, colorScheme.Focus.Foreground)
+                                 new (colorScheme!.Focus.Background, colorScheme.Focus.Foreground)
                                 );
                                 );
         }
         }
         else
         else
         {
         {
             Driver.SetAttribute (
             Driver.SetAttribute (
-                                 new Attribute (
-                                                ColorScheme.Focus.Background,
-                                                ColorScheme.Focus.Foreground
-                                               )
+                                 new (
+                                      ColorScheme.Focus.Background,
+                                      ColorScheme.Focus.Foreground
+                                     )
                                 );
                                 );
         }
         }
     }
     }
@@ -4190,67 +4184,67 @@ public class TextView : View
 
 
     private MenuBarItem BuildContextMenuBarItem ()
     private MenuBarItem BuildContextMenuBarItem ()
     {
     {
-        return new MenuBarItem (
-                                new MenuItem []
-                                {
-                                    new (
-                                         Strings.ctxSelectAll,
-                                         "",
-                                         SelectAll,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.SelectAll)
-                                        ),
-                                    new (
-                                         Strings.ctxDeleteAll,
-                                         "",
-                                         DeleteAll,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.DeleteAll)
-                                        ),
-                                    new (
-                                         Strings.ctxCopy,
-                                         "",
-                                         Copy,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.Copy)
-                                        ),
-                                    new (
-                                         Strings.ctxCut,
-                                         "",
-                                         Cut,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.Cut)
-                                        ),
-                                    new (
-                                         Strings.ctxPaste,
-                                         "",
-                                         Paste,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.Paste)
-                                        ),
-                                    new (
-                                         Strings.ctxUndo,
-                                         "",
-                                         Undo,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.Undo)
-                                        ),
-                                    new (
-                                         Strings.ctxRedo,
-                                         "",
-                                         Redo,
-                                         null,
-                                         null,
-                                         (KeyCode)KeyBindings.GetKeyFromCommands (Command.Redo)
-                                        )
-                                }
-                               );
+        return new (
+                    new MenuItem []
+                    {
+                        new (
+                             Strings.ctxSelectAll,
+                             "",
+                             SelectAll,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.SelectAll)
+                            ),
+                        new (
+                             Strings.ctxDeleteAll,
+                             "",
+                             DeleteAll,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.DeleteAll)
+                            ),
+                        new (
+                             Strings.ctxCopy,
+                             "",
+                             Copy,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Copy)
+                            ),
+                        new (
+                             Strings.ctxCut,
+                             "",
+                             Cut,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Cut)
+                            ),
+                        new (
+                             Strings.ctxPaste,
+                             "",
+                             Paste,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Paste)
+                            ),
+                        new (
+                             Strings.ctxUndo,
+                             "",
+                             Undo,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Undo)
+                            ),
+                        new (
+                             Strings.ctxRedo,
+                             "",
+                             Redo,
+                             null,
+                             null,
+                             (KeyCode)KeyBindings.GetKeyFromCommands (Command.Redo)
+                            )
+                    }
+                   );
     }
     }
 
 
     private void ClearRegion (int left, int top, int right, int bottom)
     private void ClearRegion (int left, int top, int right, int bottom)
@@ -4282,13 +4276,13 @@ public class TextView : View
         var endCol = (int)(end & 0xffffffff);
         var endCol = (int)(end & 0xffffffff);
         List<RuneCell> line = _model.GetLine (startRow);
         List<RuneCell> line = _model.GetLine (startRow);
 
 
-        _historyText.Add (new List<List<RuneCell>> { new (line) }, new Point (startCol, startRow));
+        _historyText.Add (new() { new (line) }, new (startCol, startRow));
 
 
         List<List<RuneCell>> removedLines = new ();
         List<List<RuneCell>> removedLines = new ();
 
 
         if (startRow == maxrow)
         if (startRow == maxrow)
         {
         {
-            removedLines.Add (new List<RuneCell> (line));
+            removedLines.Add (new (line));
 
 
             line.RemoveRange (startCol, endCol - startCol);
             line.RemoveRange (startCol, endCol - startCol);
             CurrentColumn = startCol;
             CurrentColumn = startCol;
@@ -4306,7 +4300,7 @@ public class TextView : View
             }
             }
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> (removedLines),
+                              new (removedLines),
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Removed
                               HistoryText.LineStatus.Removed
                              );
                              );
@@ -4316,7 +4310,7 @@ public class TextView : View
             return;
             return;
         }
         }
 
 
-        removedLines.Add (new List<RuneCell> (line));
+        removedLines.Add (new (line));
 
 
         line.RemoveRange (startCol, line.Count - startCol);
         line.RemoveRange (startCol, line.Count - startCol);
         List<RuneCell> line2 = _model.GetLine (maxrow);
         List<RuneCell> line2 = _model.GetLine (maxrow);
@@ -4324,7 +4318,7 @@ public class TextView : View
 
 
         for (int row = startRow + 1; row <= maxrow; row++)
         for (int row = startRow + 1; row <= maxrow; row++)
         {
         {
-            removedLines.Add (new List<RuneCell> (_model.GetLine (startRow + 1)));
+            removedLines.Add (new (_model.GetLine (startRow + 1)));
 
 
             _model.RemoveLine (startRow + 1);
             _model.RemoveLine (startRow + 1);
         }
         }
@@ -4337,7 +4331,7 @@ public class TextView : View
         CurrentColumn = startCol;
         CurrentColumn = startCol;
 
 
         _historyText.Add (
         _historyText.Add (
-                          new List<List<RuneCell>> (removedLines),
+                          new (removedLines),
                           CursorPosition,
                           CursorPosition,
                           HistoryText.LineStatus.Removed
                           HistoryText.LineStatus.Removed
                          );
                          );
@@ -4372,7 +4366,7 @@ public class TextView : View
             // Delete backwards 
             // Delete backwards 
             List<RuneCell> currentLine = GetCurrentLine ();
             List<RuneCell> currentLine = GetCurrentLine ();
 
 
-            _historyText.Add (new List<List<RuneCell>> { new (currentLine) }, CursorPosition);
+            _historyText.Add (new() { new (currentLine) }, CursorPosition);
 
 
             currentLine.RemoveAt (CurrentColumn - 1);
             currentLine.RemoveAt (CurrentColumn - 1);
 
 
@@ -4384,7 +4378,7 @@ public class TextView : View
             CurrentColumn--;
             CurrentColumn--;
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (currentLine) },
+                              new() { new (currentLine) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -4412,15 +4406,15 @@ public class TextView : View
             int prowIdx = CurrentRow - 1;
             int prowIdx = CurrentRow - 1;
             List<RuneCell> prevRow = _model.GetLine (prowIdx);
             List<RuneCell> prevRow = _model.GetLine (prowIdx);
 
 
-            _historyText.Add (new List<List<RuneCell>> { new (prevRow) }, CursorPosition);
+            _historyText.Add (new() { new (prevRow) }, CursorPosition);
 
 
-            List<List<RuneCell>> removedLines = new () { new List<RuneCell> (prevRow) };
+            List<List<RuneCell>> removedLines = new () { new (prevRow) };
 
 
-            removedLines.Add (new List<RuneCell> (GetCurrentLine ()));
+            removedLines.Add (new (GetCurrentLine ()));
 
 
             _historyText.Add (
             _historyText.Add (
                               removedLines,
                               removedLines,
-                              new Point (CurrentColumn, prowIdx),
+                              new (CurrentColumn, prowIdx),
                               HistoryText.LineStatus.Removed
                               HistoryText.LineStatus.Removed
                              );
                              );
 
 
@@ -4436,8 +4430,8 @@ public class TextView : View
             CurrentRow--;
             CurrentRow--;
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { GetCurrentLine () },
-                              new Point (CurrentColumn, prowIdx),
+                              new() { GetCurrentLine () },
+                              new (CurrentColumn, prowIdx),
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
 
 
@@ -4465,13 +4459,13 @@ public class TextView : View
                 return true;
                 return true;
             }
             }
 
 
-            _historyText.Add (new List<List<RuneCell>> { new (currentLine) }, CursorPosition);
+            _historyText.Add (new() { new (currentLine) }, CursorPosition);
 
 
-            List<List<RuneCell>> removedLines = new () { new List<RuneCell> (currentLine) };
+            List<List<RuneCell>> removedLines = new () { new (currentLine) };
 
 
             List<RuneCell> nextLine = _model.GetLine (CurrentRow + 1);
             List<RuneCell> nextLine = _model.GetLine (CurrentRow + 1);
 
 
-            removedLines.Add (new List<RuneCell> (nextLine));
+            removedLines.Add (new (nextLine));
 
 
             _historyText.Add (removedLines, CursorPosition, HistoryText.LineStatus.Removed);
             _historyText.Add (removedLines, CursorPosition, HistoryText.LineStatus.Removed);
 
 
@@ -4479,7 +4473,7 @@ public class TextView : View
             _model.RemoveLine (CurrentRow + 1);
             _model.RemoveLine (CurrentRow + 1);
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (currentLine) },
+                              new() { new (currentLine) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -4586,13 +4580,13 @@ public class TextView : View
         List<RuneCell> currentLine = GetCurrentLine ();
         List<RuneCell> currentLine = GetCurrentLine ();
         int cursorPosition = Math.Min (CurrentColumn, currentLine.Count);
         int cursorPosition = Math.Min (CurrentColumn, currentLine.Count);
 
 
-        Autocomplete.Context = new AutocompleteContext (
-                                                        currentLine,
-                                                        cursorPosition,
-                                                        Autocomplete.Context != null
-                                                            ? Autocomplete.Context.Canceled
-                                                            : false
-                                                       );
+        Autocomplete.Context = new (
+                                    currentLine,
+                                    cursorPosition,
+                                    Autocomplete.Context != null
+                                        ? Autocomplete.Context.Canceled
+                                        : false
+                                   );
 
 
         Autocomplete.GenerateSuggestions (
         Autocomplete.GenerateSuggestions (
                                           Autocomplete.Context
                                           Autocomplete.Context
@@ -4830,7 +4824,7 @@ public class TextView : View
 
 
         List<RuneCell> line = GetCurrentLine ();
         List<RuneCell> line = GetCurrentLine ();
 
 
-        _historyText.Add (new List<List<RuneCell>> { new (line) }, CursorPosition);
+        _historyText.Add (new() { new (line) }, CursorPosition);
 
 
         // Optimize single line
         // Optimize single line
         if (lines.Count == 1)
         if (lines.Count == 1)
@@ -4839,7 +4833,7 @@ public class TextView : View
             CurrentColumn += lines [0].Count;
             CurrentColumn += lines [0].Count;
 
 
             _historyText.Add (
             _historyText.Add (
-                              new List<List<RuneCell>> { new (line) },
+                              new() { new (line) },
                               CursorPosition,
                               CursorPosition,
                               HistoryText.LineStatus.Replaced
                               HistoryText.LineStatus.Replaced
                              );
                              );
@@ -4883,13 +4877,13 @@ public class TextView : View
 
 
         //model.AddLine (currentRow, lines [0]);
         //model.AddLine (currentRow, lines [0]);
 
 
-        List<List<RuneCell>> addedLines = new () { new List<RuneCell> (line) };
+        List<List<RuneCell>> addedLines = new () { new (line) };
 
 
         for (var i = 1; i < lines.Count; i++)
         for (var i = 1; i < lines.Count; i++)
         {
         {
             _model.AddLine (CurrentRow + i, lines [i]);
             _model.AddLine (CurrentRow + i, lines [i]);
 
 
-            addedLines.Add (new List<RuneCell> (lines [i]));
+            addedLines.Add (new (lines [i]));
         }
         }
 
 
         if (rest is { })
         if (rest is { })
@@ -4909,7 +4903,7 @@ public class TextView : View
         Adjust ();
         Adjust ();
 
 
         _historyText.Add (
         _historyText.Add (
-                          new List<List<RuneCell>> { new (line) },
+                          new() { new (line) },
                           CursorPosition,
                           CursorPosition,
                           HistoryText.LineStatus.Replaced
                           HistoryText.LineStatus.Replaced
                          );
                          );
@@ -4928,7 +4922,7 @@ public class TextView : View
 
 
         SetWrapModel ();
         SetWrapModel ();
 
 
-        _historyText.Add (new List<List<RuneCell>> { new (GetCurrentLine ()) }, CursorPosition);
+        _historyText.Add (new() { new (GetCurrentLine ()) }, CursorPosition);
 
 
         if (Selecting)
         if (Selecting)
         {
         {
@@ -4937,7 +4931,7 @@ public class TextView : View
 
 
         if ((uint)a.KeyCode == '\n')
         if ((uint)a.KeyCode == '\n')
         {
         {
-            _model.AddLine (CurrentRow + 1, new List<RuneCell> ());
+            _model.AddLine (CurrentRow + 1, new ());
             CurrentRow++;
             CurrentRow++;
             CurrentColumn = 0;
             CurrentColumn = 0;
         }
         }
@@ -4949,7 +4943,7 @@ public class TextView : View
         {
         {
             if (Used)
             if (Used)
             {
             {
-                Insert (new RuneCell { Rune = a.AsRune, ColorScheme = colorScheme });
+                Insert (new() { Rune = a.AsRune, ColorScheme = colorScheme });
                 CurrentColumn++;
                 CurrentColumn++;
 
 
                 if (CurrentColumn >= _leftColumn + Frame.Width)
                 if (CurrentColumn >= _leftColumn + Frame.Width)
@@ -4960,13 +4954,13 @@ public class TextView : View
             }
             }
             else
             else
             {
             {
-                Insert (new RuneCell { Rune = a.AsRune, ColorScheme = colorScheme });
+                Insert (new() { Rune = a.AsRune, ColorScheme = colorScheme });
                 CurrentColumn++;
                 CurrentColumn++;
             }
             }
         }
         }
 
 
         _historyText.Add (
         _historyText.Add (
-                          new List<List<RuneCell>> { new (GetCurrentLine ()) },
+                          new() { new (GetCurrentLine ()) },
                           CursorPosition,
                           CursorPosition,
                           HistoryText.LineStatus.Replaced
                           HistoryText.LineStatus.Replaced
                          );
                          );
@@ -5004,20 +4998,20 @@ public class TextView : View
             return;
             return;
         }
         }
 
 
-        _historyText.Add (new List<List<RuneCell>> { new (currentLine) }, CursorPosition);
+        _historyText.Add (new() { new (currentLine) }, CursorPosition);
 
 
         if (currentLine.Count == 0)
         if (currentLine.Count == 0)
         {
         {
             if (CurrentRow < _model.Count - 1)
             if (CurrentRow < _model.Count - 1)
             {
             {
-                List<List<RuneCell>> removedLines = new () { new List<RuneCell> (currentLine) };
+                List<List<RuneCell>> removedLines = new () { new (currentLine) };
 
 
                 _model.RemoveLine (CurrentRow);
                 _model.RemoveLine (CurrentRow);
 
 
-                removedLines.Add (new List<RuneCell> (GetCurrentLine ()));
+                removedLines.Add (new (GetCurrentLine ()));
 
 
                 _historyText.Add (
                 _historyText.Add (
-                                  new List<List<RuneCell>> (removedLines),
+                                  new (removedLines),
                                   CursorPosition,
                                   CursorPosition,
                                   HistoryText.LineStatus.Removed
                                   HistoryText.LineStatus.Removed
                                  );
                                  );
@@ -5671,13 +5665,13 @@ public class TextView : View
 
 
             if (currentLine.Count > 0 && currentLine [CurrentColumn - 1].Rune.Value == '\t')
             if (currentLine.Count > 0 && currentLine [CurrentColumn - 1].Rune.Value == '\t')
             {
             {
-                _historyText.Add (new List<List<RuneCell>> { new (currentLine) }, CursorPosition);
+                _historyText.Add (new() { new (currentLine) }, CursorPosition);
 
 
                 currentLine.RemoveAt (CurrentColumn - 1);
                 currentLine.RemoveAt (CurrentColumn - 1);
                 CurrentColumn--;
                 CurrentColumn--;
 
 
                 _historyText.Add (
                 _historyText.Add (
-                                  new List<List<RuneCell>> { new (GetCurrentLine ()) },
+                                  new() { new (GetCurrentLine ()) },
                                   CursorPosition,
                                   CursorPosition,
                                   HistoryText.LineStatus.Replaced
                                   HistoryText.LineStatus.Replaced
                                  );
                                  );
@@ -6118,7 +6112,7 @@ public class TextView : View
 
 
         List<RuneCell> currentLine = GetCurrentLine ();
         List<RuneCell> currentLine = GetCurrentLine ();
 
 
-        _historyText.Add (new List<List<RuneCell>> { new (currentLine) }, CursorPosition);
+        _historyText.Add (new() { new (currentLine) }, CursorPosition);
 
 
         if (Selecting)
         if (Selecting)
         {
         {
@@ -6130,11 +6124,11 @@ public class TextView : View
         List<RuneCell> rest = currentLine.GetRange (CurrentColumn, restCount);
         List<RuneCell> rest = currentLine.GetRange (CurrentColumn, restCount);
         currentLine.RemoveRange (CurrentColumn, restCount);
         currentLine.RemoveRange (CurrentColumn, restCount);
 
 
-        List<List<RuneCell>> addedLines = new () { new List<RuneCell> (currentLine) };
+        List<List<RuneCell>> addedLines = new () { new (currentLine) };
 
 
         _model.AddLine (CurrentRow + 1, rest);
         _model.AddLine (CurrentRow + 1, rest);
 
 
-        addedLines.Add (new List<RuneCell> (_model.GetLine (CurrentRow + 1)));
+        addedLines.Add (new (_model.GetLine (CurrentRow + 1)));
 
 
         _historyText.Add (addedLines, CursorPosition, HistoryText.LineStatus.Added);
         _historyText.Add (addedLines, CursorPosition, HistoryText.LineStatus.Added);
 
 
@@ -6151,7 +6145,7 @@ public class TextView : View
         CurrentColumn = 0;
         CurrentColumn = 0;
 
 
         _historyText.Add (
         _historyText.Add (
-                          new List<List<RuneCell>> { new (GetCurrentLine ()) },
+                          new() { new (GetCurrentLine ()) },
                           CursorPosition,
                           CursorPosition,
                           HistoryText.LineStatus.Replaced
                           HistoryText.LineStatus.Replaced
                          );
                          );
@@ -6231,7 +6225,7 @@ public class TextView : View
         {
         {
             int col = Selecting ? _selectionStartColumn : CurrentColumn;
             int col = Selecting ? _selectionStartColumn : CurrentColumn;
             int row = Selecting ? _selectionStartRow : CurrentRow;
             int row = Selecting ? _selectionStartRow : CurrentRow;
-            _model.ResetContinuousFind (new Point (col, row));
+            _model.ResetContinuousFind (new (col, row));
         }
         }
     }
     }
 
 
@@ -6243,33 +6237,11 @@ public class TextView : View
         _continuousFind = false;
         _continuousFind = false;
     }
     }
 
 
-    private void ResetCursorVisibility ()
-    {
-        if (_savedCursorVisibility != 0)
-        {
-            DesiredCursorVisibility = _savedCursorVisibility;
-            _savedCursorVisibility = 0;
-        }
-    }
 
 
     private void ResetPosition ()
     private void ResetPosition ()
     {
     {
         _topRow = _leftColumn = CurrentRow = CurrentColumn = 0;
         _topRow = _leftColumn = CurrentRow = CurrentColumn = 0;
         StopSelecting ();
         StopSelecting ();
-        ResetCursorVisibility ();
-    }
-
-    private void SaveCursorVisibility ()
-    {
-        if (_desiredCursorVisibility != CursorVisibility.Invisible)
-        {
-            if (_savedCursorVisibility == 0)
-            {
-                _savedCursorVisibility = _desiredCursorVisibility;
-            }
-
-            DesiredCursorVisibility = CursorVisibility.Invisible;
-        }
     }
     }
 
 
     private void SetClipboard (string text)
     private void SetClipboard (string text)
@@ -6342,7 +6314,7 @@ public class TextView : View
     {
     {
         // BUGBUG: (v2 truecolor) This code depends on 8-bit color names; disabling for now
         // BUGBUG: (v2 truecolor) This code depends on 8-bit color names; disabling for now
         //if ((colorScheme!.HotNormal.Foreground & colorScheme.Focus.Background) == colorScheme.Focus.Foreground) {
         //if ((colorScheme!.HotNormal.Foreground & colorScheme.Focus.Background) == colorScheme.Focus.Foreground) {
-        Driver.SetAttribute (new Attribute (colorScheme.Focus.Background, colorScheme.Focus.Foreground));
+        Driver.SetAttribute (new (colorScheme.Focus.Background, colorScheme.Focus.Foreground));
     }
     }
 
 
     /// <summary>Restore from original model.</summary>
     /// <summary>Restore from original model.</summary>
@@ -6558,6 +6530,6 @@ public class TextViewAutocomplete : PopupAutocomplete
     protected override void SetCursorPosition (int column)
     protected override void SetCursorPosition (int column)
     {
     {
         ((TextView)HostControl).CursorPosition =
         ((TextView)HostControl).CursorPosition =
-            new Point (column, ((TextView)HostControl).CurrentRow);
+            new (column, ((TextView)HostControl).CurrentRow);
     }
     }
 }
 }

+ 2 - 1
Terminal.Gui/Views/TileView.cs

@@ -987,12 +987,13 @@ public class TileView : View
             return base.OnEnter (view);
             return base.OnEnter (view);
         }
         }
 
 
-        public override void PositionCursor ()
+        public override Point? PositionCursor ()
         {
         {
             base.PositionCursor ();
             base.PositionCursor ();
 
 
             Point location = moveRuneRenderLocation ?? new Point (Viewport.Width / 2, Viewport.Height / 2);
             Point location = moveRuneRenderLocation ?? new Point (Viewport.Width / 2, Viewport.Height / 2);
             Move (location.X, location.Y);
             Move (location.X, location.Y);
+            return location;
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 8 - 6
Terminal.Gui/Views/Toplevel.cs

@@ -333,12 +333,10 @@ public partial class Toplevel : View
     }
     }
 
 
     /// <inheritdoc/>
     /// <inheritdoc/>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (!IsOverlappedContainer)
         if (!IsOverlappedContainer)
         {
         {
-            base.PositionCursor ();
-
             if (Focused is null)
             if (Focused is null)
             {
             {
                 EnsureFocus ();
                 EnsureFocus ();
@@ -349,28 +347,32 @@ public partial class Toplevel : View
                 }
                 }
             }
             }
 
 
-            return;
+            return null;
         }
         }
 
 
+        // This code path only happens when the Toplevel is an Overlapped container
+
         if (Focused is null)
         if (Focused is null)
         {
         {
+            // TODO: this is an Overlapped hack
             foreach (Toplevel top in Application.OverlappedChildren)
             foreach (Toplevel top in Application.OverlappedChildren)
             {
             {
                 if (top != this && top.Visible)
                 if (top != this && top.Visible)
                 {
                 {
                     top.SetFocus ();
                     top.SetFocus ();
 
 
-                    return;
+                    return null;
                 }
                 }
             }
             }
         }
         }
 
 
-        base.PositionCursor ();
+        var cursor2 = base.PositionCursor ();
 
 
         if (Focused is null)
         if (Focused is null)
         {
         {
             Driver.SetCursorVisibility (CursorVisibility.Invisible);
             Driver.SetCursorVisibility (CursorVisibility.Invisible);
         }
         }
+        return cursor2;
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 4 - 10
Terminal.Gui/Views/TreeView/TreeView.cs

@@ -1002,7 +1002,7 @@ public class TreeView<T> : View, ITreeView where T : class
     public bool IsSelected (T model) { return Equals (SelectedObject, model) || (MultiSelect && multiSelectedRegions.Any (s => s.Contains (model))); }
     public bool IsSelected (T model) { return Equals (SelectedObject, model) || (MultiSelect && multiSelectedRegions.Any (s => s.Contains (model))); }
 
 
     ///<inheritdoc/>
     ///<inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent me)
+    protected internal override bool OnMouseEvent (MouseEvent me)
     {
     {
         // If it is not an event we care about
         // If it is not an event we care about
         if (!me.Flags.HasFlag (MouseFlags.Button1Clicked)
         if (!me.Flags.HasFlag (MouseFlags.Button1Clicked)
@@ -1239,7 +1239,7 @@ public class TreeView<T> : View, ITreeView where T : class
     }
     }
 
 
     /// <summary>Positions the cursor at the start of the selected objects line (if visible).</summary>
     /// <summary>Positions the cursor at the start of the selected objects line (if visible).</summary>
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (CanFocus && HasFocus && Visible && SelectedObject is { })
         if (CanFocus && HasFocus && Visible && SelectedObject is { })
         {
         {
@@ -1250,16 +1250,10 @@ public class TreeView<T> : View, ITreeView where T : class
             if (idx - ScrollOffsetVertical >= 0 && idx - ScrollOffsetVertical < Viewport.Height)
             if (idx - ScrollOffsetVertical >= 0 && idx - ScrollOffsetVertical < Viewport.Height)
             {
             {
                 Move (0, idx - ScrollOffsetVertical);
                 Move (0, idx - ScrollOffsetVertical);
+                return new Point (0, idx - ScrollOffsetVertical);
             }
             }
-            else
-            {
-                base.PositionCursor ();
-            }
-        }
-        else
-        {
-            base.PositionCursor ();
         }
         }
+        return base.PositionCursor ();
     }
     }
 
 
     /// <summary>
     /// <summary>

+ 10 - 7
UICatalog/Scenarios/CharacterMap.cs

@@ -824,7 +824,7 @@ internal class CharMap : View
         return base.OnLeave (view);
         return base.OnLeave (view);
     }
     }
 
 
-    public override void PositionCursor ()
+    public override Point? PositionCursor ()
     {
     {
         if (HasFocus
         if (HasFocus
             && Cursor.X >= RowLabelWidth
             && Cursor.X >= RowLabelWidth
@@ -839,6 +839,8 @@ internal class CharMap : View
         {
         {
             Driver.SetCursorVisibility (CursorVisibility.Invisible);
             Driver.SetCursorVisibility (CursorVisibility.Invisible);
         }
         }
+
+        return Cursor;
     }
     }
 
 
     public event EventHandler<ListViewItemEventArgs> SelectedCodePointChanged;
     public event EventHandler<ListViewItemEventArgs> SelectedCodePointChanged;
@@ -870,16 +872,11 @@ internal class CharMap : View
             return;
             return;
         }
         }
 
 
-        args.Handled = true;
-
         if (me.Y == 0)
         if (me.Y == 0)
         {
         {
             me.Y = Cursor.Y;
             me.Y = Cursor.Y;
         }
         }
 
 
-        if (me.Y > 0)
-        { }
-
         if (me.X < RowLabelWidth || me.X > RowLabelWidth + 16 * COLUMN_WIDTH - 1)
         if (me.X < RowLabelWidth || me.X > RowLabelWidth + 16 * COLUMN_WIDTH - 1)
         {
         {
             me.X = Cursor.X;
             me.X = Cursor.X;
@@ -905,10 +902,16 @@ internal class CharMap : View
             Hover?.Invoke (this, new (val, null));
             Hover?.Invoke (this, new (val, null));
         }
         }
 
 
+        if (!HasFocus && CanFocus)
+        {
+            SetFocus ();
+        }
+
+        args.Handled = true;
+
         if (me.Flags == MouseFlags.Button1Clicked)
         if (me.Flags == MouseFlags.Button1Clicked)
         {
         {
             SelectedCodePoint = val;
             SelectedCodePoint = val;
-
             return;
             return;
         }
         }
 
 

+ 93 - 0
UnitTests/View/Layout/ViewportTests.cs

@@ -359,4 +359,97 @@ public class ViewportTests (ITestOutputHelper output)
         Assert.Equal (view.Viewport.Size, view.ContentSize);
         Assert.Equal (view.Viewport.Size, view.ContentSize);
     }
     }
 
 
+    //[Theory]
+    //[InlineData (0, 0, true)]
+    //[InlineData (-1, 0, true)]
+    //[InlineData (0, -1, true)]
+    //[InlineData (-1, -1, true)]
+    //[InlineData (-2, -2, true)]
+    //[InlineData (-3, -3, true)]
+    //[InlineData (-4, -4, true)]
+    //[InlineData (-5, -4, false)]
+    //[InlineData (-4, -5, false)]
+    //[InlineData (-5, -5, false)]
+
+    //[InlineData (1, 1, true)]
+    //[InlineData (2, 2, true)]
+    //[InlineData (3, 3, true)]
+    //[InlineData (4, 4, true)]
+    //[InlineData (5, 4, false)]
+    //[InlineData (4, 5, false)]
+    //[InlineData (5, 5, false)]
+    //public void IsVisibleInSuperView_No_Driver_No_SuperView (int x, int y, bool expected)
+    //{
+    //    var view = new View { X = 1, Y = 1, Width = 5, Height = 5 };
+    //    Assert.True (view.IsVisibleInSuperView (x, y) == expected);
+    //}
+
+    //[Theory]
+    //[InlineData (0, 0, true)]
+    //[InlineData (-1, 0, true)]
+    //[InlineData (0, -1, true)]
+    //[InlineData (-1, -1, true)]
+    //[InlineData (-2, -2, true)]
+    //[InlineData (-3, -3, true)]
+    //[InlineData (-4, -4, true)]
+    //[InlineData (-5, -4, true)]
+    //[InlineData (-4, -5, true)]
+    //[InlineData (-5, -5, true)]
+    //[InlineData (-6, -5, false)]
+    //[InlineData (-5, -6, false)]
+    //[InlineData (-6, -6, false)]
+
+    //[InlineData (1, 1, true)]
+    //[InlineData (2, 2, true)]
+    //[InlineData (3, 3, true)]
+    //[InlineData (4, 4, true)]
+    //[InlineData (5, 4, true)]
+    //[InlineData (4, 5, true)]
+    //[InlineData (5, 5, true)]
+    //[InlineData (6, 5, true)]
+    //[InlineData (6, 6, true)]
+    //[InlineData (7, 7, true)]
+    //[InlineData (8, 8, true)]
+    //[InlineData (9, 8, false)]
+    //[InlineData (8, 9, false)]
+    //[InlineData (9, 9, false)]
+    //public void IsVisibleInSuperView_No_Driver_With_SuperView (int x, int y, bool expected)
+    //{
+    //    var view = new View { X = 1, Y = 1, Width = 5, Height = 5 };
+    //    var top = new Toplevel { Width = 10, Height = 10 };
+    //    top.Add (view);
+
+    //    Assert.True (view.IsVisibleInSuperView (x, y) == expected);
+    //}
+
+    //[SetupFakeDriver]
+    //[Theory]
+    //[InlineData (0, 0, true)]
+    //[InlineData (-1, 0, false)]
+    //[InlineData (0, -1, false)]
+    //[InlineData (-1, -1, false)]
+
+    //[InlineData (1, 0, true)]
+    //[InlineData (0, 1, true)]
+    //[InlineData (1, 1, true)]
+    //[InlineData (2, 2, true)]
+    //[InlineData (3, 3, true)]
+    //[InlineData (4, 4, true)]
+    //[InlineData (5, 4, false)]
+    //[InlineData (4, 5, false)]
+    //[InlineData (5, 5, false)]
+    //public void IsVisibleInSuperView_With_Driver (int x, int y, bool expected)
+    //{
+    //    ((FakeDriver)Application.Driver).SetBufferSize (10, 10);
+
+    //    var view = new View { X = 1, Y = 1, Width = 5, Height = 5 };
+    //    var top = new Toplevel ();
+    //    top.Add (view);
+    //    Application.Begin (top);
+
+    //    Assert.True (view.IsVisibleInSuperView (x, y) == expected);
+
+    //    top.Dispose ();
+    //    Application.Shutdown ();
+    //}
 }
 }

+ 32 - 12
UnitTests/Views/TextViewTests.cs

@@ -1065,34 +1065,44 @@ This is the second line.
 
 
         var tv = new TextView { Width = 10, Height = 10 };
         var tv = new TextView { Width = 10, Height = 10 };
         tv.Text = text;
         tv.Text = text;
+        var top = new Toplevel ();
+        top.Add (tv);
+        Application.Begin (top);
 
 
         Assert.Equal (0, tv.LeftColumn);
         Assert.Equal (0, tv.LeftColumn);
-        tv.PositionCursor ();
+        Assert.Equal (Point.Empty, tv.CursorPosition);
+        Application.PositionCursor (top);
         Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility);
         Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility);
 
 
         for (var i = 0; i < 12; i++)
         for (var i = 0; i < 12; i++)
         {
         {
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight });
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight });
-            tv.PositionCursor ();
             Assert.Equal (Math.Min (i + 1, 11), tv.LeftColumn);
             Assert.Equal (Math.Min (i + 1, 11), tv.LeftColumn);
-            Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility);
+            Application.PositionCursor (top);
+            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+            Assert.Equal (CursorVisibility.Invisible, cursorVisibility);
         }
         }
 
 
         for (var i = 11; i > 0; i--)
         for (var i = 11; i > 0; i--)
         {
         {
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledLeft });
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledLeft });
-            tv.PositionCursor ();
             Assert.Equal (i - 1, tv.LeftColumn);
             Assert.Equal (i - 1, tv.LeftColumn);
 
 
+            Application.PositionCursor (top);
+            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+
             if (i - 1 == 0)
             if (i - 1 == 0)
             {
             {
-                Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility);
+                Assert.Equal (CursorVisibility.Default, cursorVisibility);
             }
             }
             else
             else
             {
             {
-                Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility);
+                Assert.Equal (CursorVisibility.Invisible, cursorVisibility);
             }
             }
         }
         }
+
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     [Fact]
     [Fact]
@@ -1108,34 +1118,44 @@ This is the second line.
 
 
         var tv = new TextView { Width = 10, Height = 10 };
         var tv = new TextView { Width = 10, Height = 10 };
         tv.Text = text;
         tv.Text = text;
+        var top = new Toplevel ();
+        top.Add (tv);
+        Application.Begin (top);
 
 
         Assert.Equal (0, tv.TopRow);
         Assert.Equal (0, tv.TopRow);
-        tv.PositionCursor ();
+        Application.PositionCursor (top);
         Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility);
         Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility);
 
 
         for (var i = 0; i < 12; i++)
         for (var i = 0; i < 12; i++)
         {
         {
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown });
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown });
-            tv.PositionCursor ();
+            Application.PositionCursor (top);
             Assert.Equal (i + 1, tv.TopRow);
             Assert.Equal (i + 1, tv.TopRow);
-            Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility);
+            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+            Assert.Equal (CursorVisibility.Invisible, cursorVisibility);
         }
         }
 
 
         for (var i = 12; i > 0; i--)
         for (var i = 12; i > 0; i--)
         {
         {
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledUp });
             tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledUp });
-            tv.PositionCursor ();
+            Application.PositionCursor (top);
             Assert.Equal (i - 1, tv.TopRow);
             Assert.Equal (i - 1, tv.TopRow);
 
 
+            Application.PositionCursor (top);
+            Application.Driver.GetCursorVisibility (out CursorVisibility cursorVisibility);
+
             if (i - 1 == 0)
             if (i - 1 == 0)
             {
             {
-                Assert.Equal (CursorVisibility.Default, tv.DesiredCursorVisibility);
+                Assert.Equal (CursorVisibility.Default, cursorVisibility);
             }
             }
             else
             else
             {
             {
-                Assert.Equal (CursorVisibility.Invisible, tv.DesiredCursorVisibility);
+                Assert.Equal (CursorVisibility.Invisible, cursorVisibility);
             }
             }
         }
         }
+
+        top.Dispose ();
+        Application.Shutdown ();
     }
     }
 
 
     [Fact]
     [Fact]

+ 2 - 1
UnitTests/Views/ToplevelTests.cs

@@ -1261,12 +1261,13 @@ public class ToplevelTests
         Application.Begin (top);
         Application.Begin (top);
 
 
         Assert.True (tf.HasFocus);
         Assert.True (tf.HasFocus);
+        Application.PositionCursor (top);
         Application.Driver.GetCursorVisibility (out CursorVisibility cursor);
         Application.Driver.GetCursorVisibility (out CursorVisibility cursor);
         Assert.Equal (CursorVisibility.Default, cursor);
         Assert.Equal (CursorVisibility.Default, cursor);
 
 
         view.Enabled = false;
         view.Enabled = false;
         Assert.False (tf.HasFocus);
         Assert.False (tf.HasFocus);
-        Application.Refresh ();
+        Application.PositionCursor (top);
         Application.Driver.GetCursorVisibility (out cursor);
         Application.Driver.GetCursorVisibility (out cursor);
         Assert.Equal (CursorVisibility.Invisible, cursor);
         Assert.Equal (CursorVisibility.Invisible, cursor);
     }
     }

+ 162 - 0
docfx/docs/cursor.md

@@ -0,0 +1,162 @@
+# Proposed Design for a modern Cursor system in v2
+
+See end for list of issues this design addresses.
+
+## Tenets for Cursor Support (Unless you know better ones...)
+
+1. **More GUI than Command Line**. The concept of a cursor on the command line of a terminal is intrinsically tied to enabling the user to know where keybaord import is going to impact text editing. TUI apps have many more modalities than text editing where the keyboard is used (e.g. scrolling through a `ColorPicker`). Terminal.Gui's cursor system is biased towards the broader TUI experiences.
+
+2. **Be Consistent With the User's Platform** - Users get to choose the platform they run *Terminal.Gui* apps on and the cursor should behave in a way consistent with the terminal.
+
+## Lexicon & Taxonomy
+
+- Cursor - A visual indicator to the user where keyboard input will have an impact. There is one Cursor per terminal sesssion.
+- Cursor Location - The top-left corner of the Cursor. In text entry scenarios, new text will be inserted to the left/top of the Cursor Location. 
+- Cursor Size - The width and height of the cursor. Currently the size is limited to 1x1.
+- Cursor Style - How the cursor renders. Some terminals support various cursor styles such as Block and Underline.
+- Cursor Visibilty - Whether the cursor is visible to the user or not. NOTE: Some ConsoleDrivers overload Cursor Style and Cursor Visibility, making "invisible" a style. Terminal.Gui HIDES this from developers and changing the visibilty of the cursor does NOT change the style.
+- Caret - Visual indicator that  where text entry will occur. 
+- Selection - A visual indicator to the user that something is selected. It is common for the Selection and Cursor to be the same. It is also common for the Selection and Cursor to be distinct. In a `ListView` the Cursor and Selection (`SelectedItem`) are the same, but the `Cursor` is not visible. In a `TextView` with text selected, the `Cursor` is at either the start or end of the `Selection`. A `TableView' supports mutliple things being selected at once.
+
+## Requirements
+
+- No flickering. The Cursor should blink/pulse at the rate dictated by the terminal. Typing, moving the mouse, view layout, etc... should not caue the cursor to flicker.
+- By default, the Cursor should not be visible. A View or View subclass should have to do anything (this is already the case) to keep the Cursor invisible.
+- Views that just want to show the cursor at a particular location in the Viewport should only have to:
+  - Optionally, declare a desired Cursor Style. Set `Application.CursorStyle`.
+  - Indicate the Cursor Locaiton when internal state dictates the location has changed (debatable if this should be in content or viewport-relative coords). Just set `this.CursorPosition`.
+  - To hide the cursor, simply set `this.CursorPostion` to `null`.
+- The Cursor should only be visible in Views where
+  - `Enabled == true`
+  - `Visible == true`
+  - `CanFocus == true`
+  - `this == SuperView.MostFocused`
+- If a `ConsoleDriver` supports Cursor Styles other than Default, they should be supported per-application (NOT View). 
+- Ensuring the cursor is visible or not should be handled by `Application`, not `View`.
+- General V2 Requirement: View sub-class code should NEVER call a `Driver.` API. Only `Application` and the `View` base class should call `ConsoleDriver` APIs; before we ship v2, all `ConsoleDriver` APIs will be made `internal`.
+
+## Design
+
+### `View` Focus Changes
+
+It doesn't make sense the every View instance has it's own notion of `MostFocused`. The current implemention is overly complicated and fragile because the concept of "MostFocused" is handled by `View`. There can be only ONE "most focused" view in an application. `MostFocused` should be a property on `Application`.
+
+* Remove `View.MostFocused`
+* Change all references to access `Application.MostFocusedView` (see `Application` below)
+* Find all instances of `view._hasFocus = ` and change them to use `SetHasFocus` (today, anyplace that sets `_hasFocus` is a BUG!!).
+* Change `SetFocus`/`SetHasFocus` etc... such that if the focus is changed to a different view heirarchy, `Application.MostFocusedView` gets set appropriately. 
+
+**MORE THOUGHT REQUIRED HERE** - There be dragons given how `Toplevel` has `OnEnter/OnLeave` overrrides. The above needs more study, but is directioally correct.
+
+### `View` Cursor Changes
+* Add `public Point? CursorPosition`
+    - Backed with `private Point? _cursorPosition`
+    - If `!HasValue` the cursor is not visible
+    - If `HasValue` the cursor is visible at the Point.
+    - On set, if `value != _cursorPosition`, call `OnCursorPositionChanged()`
+* Add `public event EventHandler<LocaitonChangedEventArgs>? CursorPositionChanged`
+* Add `internal void OnCursorPositionChanged(LocationChangedEventArgs a)`
+  * Not virtual
+  * Fires `CursorPositionChanged`
+
+### `ConsoleDriver`s
+
+* Remove `Refresh` and have `UpdateScreen` and `UpdateCursor` be called separately. The fact that `Refresh` in all drivers currently calls both is a source of flicker.
+
+* Remove the `xxxCursorVisibility` APIs and replace with:
+  * `internal int CursorStyle {get; internal set; }`
+    - Backed with `private int _cursorStyle`
+    - On set, calls `OnCursorStyleChanged()`
+  * Add `internal abstract void OnCursorStyleChanged()`
+    - Called by `base` whenever the cursor style changes, but ONLY if `value != _cursorStyle`.
+
+  * Add `internal virtual (int Id, string StyleName) []  GetCursorStyles()`
+    - Returns an array of styles supported by the driver, NOT including Invisible. 
+    - The first item in array is always "Default".
+    - Base implementation returns `{ 0, "Default" }`
+    - `CursesDriver` and `WindowsDriver` will need to implement overrides.
+
+  * Add `internal Point? CursorPosition {get; internal set; }`
+    - Backed with `private Point? _cursorPosition`
+    - If `!HasValue` the cursor is not visible
+    - If `HasValue` the cursor is visible at the Point.
+    - On set, calls `OnCursorPositionChanged` ONLY if `value != _cursorPosition`.
+  * Add `internal abstract void OnCursorPositionChanged()`
+    - Called by `base` whenever the cursor position changes. 
+    - Depending on the value of `CursorPosition`:
+        - If `!HasValue` the cursor is not visible - does whatever is needed to make the cursor invisible.
+        - If `HasValue` the cursor is visible at the `CursorPosition` - does whatever is needed to make the cursor visible (using `CursorStyle`).
+
+  * Make sure the drivers only make the cursor visible (or leave it visible) when `CursorPosition` changes!
+
+### `Application`
+
+* 
+
+* Add `internal static View FocusedView {get; private set;}` 
+  - Backed by `private static _focusedView`
+  - On set, 
+    - if `value != _focusedView` 
+        - Unsubscribe from `_focusedView.CursorPositionChanged`
+        - Subscribe to `value.CursorPositionChanged += CursorPositionChanged`        
+        - `_focusedView = value`
+        - Call `UpdateCursor` 
+
+* Add `internal bool CursorPositionChanged (object sender, LocationChangedEventArgs a)`
+
+    Called when:
+
+    - `FocusedView`
+        - Has changed to another View (should cover `FocusedView.Visible/Enable` changes)
+        - Has changed layout - 
+        - Has changeed it's `CursorPosition`
+    - `CursorStyle` has changed
+
+    Does:
+
+    - If `FocusedView is {}` and `FocusedView.CursorPosition` is visible (e.g. w/in `FocusedView.SuperView.Viewport`) 
+        - Does `Driver.CursorPosition = ToScreen(FocusedView.CursorPosition)`
+    - Else
+        - Makes driver cursor invisible with `Driver.CursorPosition = null`
+
+* Add `public static int CursorStyle {get; internal set; }`
+  - Backed with `private static int _cursorStyle
+  - If `value != _cursorStyle`
+    - Calls `ConsoleDriver.CursorStyle = _cursorStyle` 
+    - Calls `UpdateCursor`
+
+* Add `public (int Id, string StyleName) []  GetCursorStyles()`
+  - Calls through to `ConsoleDriver.GetCursorStyles()`
+
+
+
+# Issues with Current Design
+
+## `Driver.Row/Pos`, which are changed via `Move` serves two purposes that confuse each other:
+
+a) Where the next `AddRune` will put the next rune
+b) The current "Cursor Location"
+
+If most TUI apps acted like a command line where the visible cursor was always visible, this might make sense. But the fact that only a very few View subclasses we've seen actually care to show the cursor illustrates a problem:
+
+Any drawing causes the "Cursor Position" to be changed/lost. This means we have a ton of code that is constantly repositioning the cursor every MainLoop iteration.
+
+## The actual cursor position RARELY changes (relative to `Mainloop.Iteration`).
+
+Derived from abo`ve, the current design means we need to call `View.PositionCursor` every iteration. For some views this is a low-cost operation. For others it involves a lot of math. 
+
+This is just stupid. 
+
+## Flicker
+
+Related to the above, we need constantly Show/Hide the cursor every iteration. This causes ridiculous cursor flicker. 
+
+## `View.PositionCursor` is poorly spec'd and confusing to implement correctly
+
+Should a view call `base.PositionCursor`? If so, before or after doing stuff? 
+
+## Setting cursor visibility in `OnEnter` actually makes no sense
+
+First, leaving it up to views to do this is fragile.
+
+Second, when a View gets focus is but one of many places where cursor visibilty should be updated.