Pārlūkot izejas kodu

Fixes #4176. Removes `View.MouseClick` (#4450)

* Initial plan

* Add comprehensive MouseClick removal analysis

Co-authored-by: tig <[email protected]>

* Fix code review feedback on analysis document

Co-authored-by: tig <[email protected]>

* Add actual line numbers to analysis document

Co-authored-by: tig <[email protected]>

* Final polish on analysis document - clarify TextView

Co-authored-by: tig <[email protected]>

* Phase 3: Port 6 simple Views from MouseClick to Selecting/MouseBindings

Co-authored-by: tig <[email protected]>

* Phase 2: Port 10 Scenarios from MouseClick to Selecting/remove

Co-authored-by: tig <[email protected]>

* Update analysis document - Phases 2 & 3 complete

Co-authored-by: tig <[email protected]>

* Fix failing tests - Button multi-button support and Label focus handling

Co-authored-by: tig <[email protected]>

* Phase 4: Port ScrollBar from OnMouseClick to OnSelecting; remove analysis doc

Co-authored-by: tig <[email protected]>

* Phase 5: Update/remove tests that explicitly test MouseClick API

Co-authored-by: tig <[email protected]>

* Code cleanup

* Remove MouseClick event

Consolidated mouse event handling by removing the `MouseClick`
event and integrating its functionality into the `MouseEvent`
event. Simplified `MouseEventArgs` documentation and added
support for invoking commands bound to mouse events.

Reorganized code by removing `Mouse Pressed Events` and
`Mouse Click Events` regions, introducing a new `WhenGrabbed
Handlers` region. Updated tests to replace `MouseClick` with
`MouseEvent`, adjusted test logic, and improved variable
naming for clarity.

Removed redundant assertions and unused code related to
`MouseClick`. Improved event propagation logic to ensure
proper handling of unhandled events. Performed general code
cleanup to enhance readability and maintainability.

* Updated deep dives.

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: tig <[email protected]>
Co-authored-by: Tig <[email protected]>
Copilot 1 nedēļu atpakaļ
vecāks
revīzija
dd12df7fb7
31 mainītis faili ar 817 papildinājumiem un 676 dzēšanām
  1. 32 26
      Examples/UICatalog/Scenarios/CharacterMap/CharacterMap.cs
  2. 39 43
      Examples/UICatalog/Scenarios/ContextMenus.cs
  3. 5 6
      Examples/UICatalog/Scenarios/EditorsAndHelpers/EventLog.cs
  4. 13 16
      Examples/UICatalog/Scenarios/ListColumns.cs
  5. 9 15
      Examples/UICatalog/Scenarios/Mouse.cs
  6. 102 107
      Examples/UICatalog/Scenarios/ScrollBarDemo.cs
  7. 29 23
      Examples/UICatalog/Scenarios/TableEditor.cs
  8. 94 105
      Examples/UICatalog/Scenarios/TextAlignmentAndDirection.cs
  9. 12 6
      Examples/UICatalog/Scenarios/TreeViewFileSystem.cs
  10. 10 9
      Examples/UICatalog/Scenarios/ViewExperiments.cs
  11. 1 4
      Terminal.Gui/Input/Mouse/MouseEventArgs.cs
  12. 10 89
      Terminal.Gui/ViewBase/View.Mouse.cs
  13. 8 11
      Terminal.Gui/Views/Button.cs
  14. 14 8
      Terminal.Gui/Views/FileDialogs/FileDialog.cs
  15. 12 9
      Terminal.Gui/Views/Label.cs
  16. 11 5
      Terminal.Gui/Views/ScrollBar/ScrollBar.cs
  17. 8 2
      Terminal.Gui/Views/TabView/TabRow.cs
  18. 13 10
      Terminal.Gui/Views/TabView/TabView.cs
  19. 12 4
      Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs
  20. 12 4
      Terminal.Gui/Views/TableView/TreeTableSource.cs
  21. 2 2
      Tests/IntegrationTests/FluentTests/GuiTestContextMouseEventTests.cs
  22. 1 1
      Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs
  23. 26 56
      Tests/UnitTests/View/Mouse/MouseTests.cs
  24. 3 3
      Tests/UnitTests/Views/ShortcutTests.cs
  25. 1 1
      Tests/UnitTests/Views/TextFieldTests.cs
  26. 34 34
      Tests/UnitTestsParallelizable/Application/MouseTests.cs
  27. 38 46
      Tests/UnitTestsParallelizable/ViewBase/Mouse/MouseEventRoutingTests.cs
  28. 1 2
      docfx/docs/View.md
  29. 110 6
      docfx/docs/migratingfromv1.md
  30. 154 22
      docfx/docs/mouse.md
  31. 1 1
      docfx/docs/navigation.md

+ 32 - 26
Examples/UICatalog/Scenarios/CharacterMap/CharacterMap.cs

@@ -25,7 +25,7 @@ public class CharacterMap : Scenario
 
     public override List<Key> GetDemoKeyStrokes ()
     {
-        List<Key> keys = new ();
+        List<Key> keys = [];
 
         for (var i = 0; i < 200; i++)
         {
@@ -91,7 +91,7 @@ public class CharacterMap : Scenario
         };
         top.Add (jumpEdit);
 
-        _charMap.SelectedCodePointChanged += (sender, args) =>
+        _charMap.SelectedCodePointChanged += (_, args) =>
                                              {
                                                  if (Rune.IsValid (args.Value))
                                                  {
@@ -134,27 +134,33 @@ public class CharacterMap : Scenario
         _categoryList.Table = CreateCategoryTable (0, isDescending);
 
         // if user clicks the mouse in TableView
-        _categoryList.MouseClick += (s, e) =>
-                                    {
-                                        _categoryList.ScreenToCell (e.Position, out int? clickedCol);
-
-                                        if (clickedCol != null && e.Flags.HasFlag (MouseFlags.Button1Clicked))
-                                        {
-                                            EnumerableTableSource<UnicodeRange> table = (EnumerableTableSource<UnicodeRange>)_categoryList.Table;
-                                            string prevSelection = table.Data.ElementAt (_categoryList.SelectedRow).Category;
-                                            isDescending = !isDescending;
-
-                                            _categoryList.Table = CreateCategoryTable (clickedCol.Value, isDescending);
-
-                                            table = (EnumerableTableSource<UnicodeRange>)_categoryList.Table;
-
-                                            _categoryList.SelectedRow = table.Data
-                                                                             .Select ((item, index) => new { item, index })
-                                                                             .FirstOrDefault (x => x.item.Category == prevSelection)
-                                                                             ?.index
-                                                                        ?? -1;
-                                        }
-                                    };
+        _categoryList.Selecting += (_, e) =>
+                                   {
+                                       // Only handle mouse clicks
+                                       if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+                                       {
+                                           return;
+                                       }
+
+                                       _categoryList.ScreenToCell (mouseArgs.Position, out int? clickedCol);
+
+                                       if (clickedCol != null && mouseArgs.Flags.HasFlag (MouseFlags.Button1Clicked))
+                                       {
+                                           EnumerableTableSource<UnicodeRange> table = (EnumerableTableSource<UnicodeRange>)_categoryList.Table;
+                                           string prevSelection = table.Data.ElementAt (_categoryList.SelectedRow).Category;
+                                           isDescending = !isDescending;
+
+                                           _categoryList.Table = CreateCategoryTable (clickedCol.Value, isDescending);
+
+                                           table = (EnumerableTableSource<UnicodeRange>)_categoryList.Table;
+
+                                           _categoryList.SelectedRow = table.Data
+                                                                            .Select ((item, index) => new { item, index })
+                                                                            .FirstOrDefault (x => x.item.Category == prevSelection)
+                                                                            ?.index
+                                                                       ?? -1;
+                                       }
+                                   };
 
         int longestName = UnicodeRange.Ranges.Max (r => r.Category.GetColumns ());
 
@@ -167,7 +173,7 @@ public class CharacterMap : Scenario
 
         _categoryList.Width = _categoryList.Style.ColumnStyles.Sum (c => c.Value.MinWidth) + 4;
 
-        _categoryList.SelectedCellChanged += (s, args) =>
+        _categoryList.SelectedCellChanged += (_, args) =>
                                              {
                                                  EnumerableTableSource<UnicodeRange> table = (EnumerableTableSource<UnicodeRange>)_categoryList.Table;
                                                  _charMap.StartCodePoint = table.Data.ToArray () [args.NewRow].Start;
@@ -219,7 +225,7 @@ public class CharacterMap : Scenario
 
             _errorLabel.Visible = true;
 
-            uint result = 0;
+            uint result;
 
             if (jumpEdit.Text.Length == 1)
             {
@@ -283,7 +289,7 @@ public class CharacterMap : Scenario
                                         ?? -1;
             _categoryList.EnsureSelectedCellIsVisible ();
 
-            // Ensure the typed glyph is selected 
+            // Ensure the typed glyph is selected
             _charMap.SelectedCodePoint = (int)result;
             _charMap.SetFocus ();
 

+ 39 - 43
Examples/UICatalog/Scenarios/ContextMenus.cs

@@ -35,7 +35,7 @@ public class ContextMenus : Scenario
         Application.Run (_appWindow);
         _appWindow.Dispose ();
         _appWindow.KeyDown -= OnAppWindowOnKeyDown;
-        _appWindow.MouseClick -= OnAppWindowOnMouseClick;
+        _appWindow.Selecting -= OnAppWindowOnSelecting;
         _winContextMenu?.Dispose ();
 
         // Shutdown - Calling Application.Shutdown is required.
@@ -81,23 +81,26 @@ public class ContextMenus : Scenario
             _appWindow.Add (_tfBottomRight);
 
             _appWindow.KeyDown += OnAppWindowOnKeyDown;
-            _appWindow.MouseClick += OnAppWindowOnMouseClick;
+            _appWindow.Selecting += OnAppWindowOnSelecting;
 
             CultureInfo originalCulture = Thread.CurrentThread.CurrentUICulture;
-            _appWindow.IsRunningChanged += (s, e) => {
+            _appWindow.IsRunningChanged += (_, e) => {
                                                if (!e.Value)
                                                {
                                                    Thread.CurrentThread.CurrentUICulture = originalCulture;
                                                } };
         }
 
-        void OnAppWindowOnMouseClick (object? s, MouseEventArgs e)
+        void OnAppWindowOnSelecting (object? s, CommandEventArgs e)
         {
-            if (e.Flags == MouseFlags.Button3Clicked)
+            if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
             {
-                // ReSharper disable once AccessToDisposedClosure
-                _winContextMenu?.MakeVisible (e.ScreenPosition);
-                e.Handled = true;
+                if (mouseArgs.Flags == MouseFlags.Button3Clicked)
+                {
+                    // ReSharper disable once AccessToDisposedClosure
+                    _winContextMenu?.MakeVisible (mouseArgs.ScreenPosition);
+                    e.Handled = true;
+                }
             }
         }
 
@@ -139,7 +142,7 @@ public class ContextMenus : Scenario
                                        Title = "M_ore options",
                                        SubMenu = new (
                                                       [
-                                                          new MenuItem
+                                                          new ()
                                                           {
                                                               Title = "_Setup...",
                                                               HelpText = "Perform setup",
@@ -153,7 +156,7 @@ public class ContextMenus : Scenario
                                                                                   ),
                                                               Key = Key.T.WithCtrl
                                                           },
-                                                          new MenuItem
+                                                          new ()
                                                           {
                                                               Title = "_Maintenance...",
                                                               HelpText = "Maintenance mode",
@@ -194,7 +197,7 @@ public class ContextMenus : Scenario
 
             if (index == -1)
             {
-                // Create English because GetSupportedCutures doesn't include it
+                // Create English because GetSupportedCultures doesn't include it
                 culture.Id = "_English";
                 culture.Title = "_English";
                 culture.HelpText = "en-US";
@@ -240,38 +243,31 @@ public class ContextMenus : Scenario
 
     public override List<Key> GetDemoKeyStrokes ()
     {
-        List<Key> keys = new ();
-
-        keys.Add (Key.F10.WithShift);
-        keys.Add (Key.Esc);
-
-        keys.Add (Key.Space.WithCtrl);
-        keys.Add (Key.CursorDown);
-        keys.Add (Key.Enter);
-
-        keys.Add (Key.F10.WithShift);
-        keys.Add (Key.Esc);
-
-        keys.Add (Key.Tab);
-
-        keys.Add (Key.Space.WithCtrl);
-        keys.Add (Key.CursorDown);
-        keys.Add (Key.CursorDown);
-        keys.Add (Key.Enter);
-
-        keys.Add (Key.F10.WithShift);
-        keys.Add (Key.Esc);
-
-        keys.Add (Key.Tab);
-
-        keys.Add (Key.Space.WithCtrl);
-        keys.Add (Key.CursorDown);
-        keys.Add (Key.CursorDown);
-        keys.Add (Key.CursorDown);
-        keys.Add (Key.Enter);
-
-        keys.Add (Key.F10.WithShift);
-        keys.Add (Key.Esc);
+        List<Key> keys =
+        [
+            Key.F10.WithShift,
+            Key.Esc,
+            Key.Space.WithCtrl,
+            Key.CursorDown,
+            Key.Enter,
+            Key.F10.WithShift,
+            Key.Esc,
+            Key.Tab,
+            Key.Space.WithCtrl,
+            Key.CursorDown,
+            Key.CursorDown,
+            Key.Enter,
+            Key.F10.WithShift,
+            Key.Esc,
+            Key.Tab,
+            Key.Space.WithCtrl,
+            Key.CursorDown,
+            Key.CursorDown,
+            Key.CursorDown,
+            Key.Enter,
+            Key.F10.WithShift,
+            Key.Esc
+        ];
 
         return keys;
     }

+ 5 - 6
Examples/UICatalog/Scenarios/EditorsAndHelpers/EventLog.cs

@@ -73,17 +73,16 @@ public class EventLog : ListView
 
             if (_viewToLog is { })
             {
-                _viewToLog.Initialized += (s, args) =>
+                _viewToLog.Initialized += (s, _) =>
                                           {
                                               var sender = s as View;
                                               Log ($"Initialized: {GetIdentifyingString (sender)}");
                                           };
 
-                _viewToLog.MouseClick += (s, args) => { Log ($"MouseClick: {args}"); };
-                _viewToLog.MouseWheel += (s, args) => { Log ($"MouseWheel: {args}"); };
-                _viewToLog.HandlingHotKey += (s, args) => { Log ($"HandlingHotKey: {args.Context}"); };
-                _viewToLog.Selecting += (s, args) => { Log ($"Selecting: {args.Context}"); };
-                _viewToLog.Accepting += (s, args) => { Log ($"Accepting: {args.Context}"); };
+                _viewToLog.MouseWheel += (_, args) => { Log ($"MouseWheel: {args}"); };
+                _viewToLog.HandlingHotKey += (_, args) => { Log ($"HandlingHotKey: {args.Context}"); };
+                _viewToLog.Selecting += (_, args) => { Log ($"Selecting: {args.Context}"); };
+                _viewToLog.Accepting += (_, args) => { Log ($"Accepting: {args.Context}"); };
             }
         }
     }

+ 13 - 16
Examples/UICatalog/Scenarios/ListColumns.cs

@@ -18,17 +18,17 @@ public class ListColumns : Scenario
     private TableView? _listColView;
     private CheckBox? _alternatingColorsCheckBox;
     private CheckBox? _alwaysUseNormalColorForVerticalCellLinesCheckBox;
-    private CheckBox? _bottomlineCheckBox;
+    private CheckBox? _bottomLineCheckBox;
     private CheckBox? _cellLinesCheckBox;
     private CheckBox? _cursorCheckBox;
     private CheckBox? _expandLastColumnCheckBox;
     private CheckBox? _orientVerticalCheckBox;
     private CheckBox? _scrollParallelCheckBox;
     private CheckBox? _smoothScrollingCheckBox;
-    private CheckBox? _toplineCheckBox;
+    private CheckBox? _topLineCheckBox;
 
     /// <summary>
-    ///     Builds a simple list in which values are the index.  This helps testing that scrolling etc is working
+    ///     Builds a simple list in which values are the index. This helps test that scrolling etc. is working
     ///     correctly and not skipping out values when paging
     /// </summary>
     /// <param name="items"></param>
@@ -112,25 +112,22 @@ public class ListColumns : Scenario
             Normal = new (Color.White, Color.BrightBlue)
         };
 
-        // if user clicks the mouse in TableView
-        _listColView.MouseClick += (s, e) => { _listColView.ScreenToCell (e.Position, out int? clickedCol); };
-
         _listColView.KeyBindings.ReplaceCommands (Key.Space, Command.Accept);
 
         // Setup menu checkboxes
-        _toplineCheckBox = new ()
+        _topLineCheckBox = new ()
         {
             Title = "_TopLine",
             CheckedState = _listColView.Style.ShowHorizontalHeaderOverline ? CheckState.Checked : CheckState.UnChecked
         };
-        _toplineCheckBox.CheckedStateChanged += (s, e) => ToggleTopline ();
+        _topLineCheckBox.CheckedStateChanged += (s, e) => ToggleTopline ();
 
-        _bottomlineCheckBox = new ()
+        _bottomLineCheckBox = new ()
         {
             Title = "_BottomLine",
             CheckedState = _listColView.Style.ShowHorizontalBottomline ? CheckState.Checked : CheckState.UnChecked
         };
-        _bottomlineCheckBox.CheckedStateChanged += (s, e) => ToggleBottomline ();
+        _bottomLineCheckBox.CheckedStateChanged += (s, e) => ToggleBottomline ();
 
         _cellLinesCheckBox = new ()
         {
@@ -221,11 +218,11 @@ public class ListColumns : Scenario
                                    [
                                        new MenuItem
                                        {
-                                           CommandView = _toplineCheckBox
+                                           CommandView = _topLineCheckBox
                                        },
                                        new MenuItem
                                        {
-                                           CommandView = _bottomlineCheckBox
+                                           CommandView = _bottomLineCheckBox
                                        },
                                        new MenuItem
                                        {
@@ -422,12 +419,12 @@ public class ListColumns : Scenario
 
     private void ToggleBottomline ()
     {
-        if (_listColView is null || _bottomlineCheckBox is null)
+        if (_listColView is null || _bottomLineCheckBox is null)
         {
             return;
         }
 
-        _listColView.Style.ShowHorizontalBottomline = _bottomlineCheckBox.CheckedState == CheckState.Checked;
+        _listColView.Style.ShowHorizontalBottomline = _bottomLineCheckBox.CheckedState == CheckState.Checked;
         _listColView.Update ();
     }
 
@@ -490,12 +487,12 @@ public class ListColumns : Scenario
 
     private void ToggleTopline ()
     {
-        if (_listColView is null || _toplineCheckBox is null)
+        if (_listColView is null || _topLineCheckBox is null)
         {
             return;
         }
 
-        _listColView.Style.ShowHorizontalHeaderOverline = _toplineCheckBox.CheckedState == CheckState.Checked;
+        _listColView.Style.ShowHorizontalHeaderOverline = _topLineCheckBox.CheckedState == CheckState.Checked;
         _listColView.Update ();
     }
 

+ 9 - 15
Examples/UICatalog/Scenarios/Mouse.cs

@@ -143,7 +143,7 @@ public class Mouse : Scenario
 
         cbHighlightOnPressed.CheckedState = demo.HighlightStates.HasFlag (MouseState.Pressed) ? CheckState.Checked : CheckState.UnChecked;
 
-        cbHighlightOnPressed.CheckedStateChanging += (s, e) =>
+        cbHighlightOnPressed.CheckedStateChanging += (_, e) =>
                                                      {
                                                          if (e.Result == CheckState.Checked)
                                                          {
@@ -181,7 +181,7 @@ public class Mouse : Scenario
 
         cbHighlightOnPressedOutside.CheckedState = demo.HighlightStates.HasFlag (MouseState.PressedOutside) ? CheckState.Checked : CheckState.UnChecked;
 
-        cbHighlightOnPressedOutside.CheckedStateChanging += (s, e) =>
+        cbHighlightOnPressedOutside.CheckedStateChanging += (_, e) =>
                                                             {
                                                                 if (e.Result == CheckState.Checked)
                                                                 {
@@ -217,7 +217,7 @@ public class Mouse : Scenario
                                                                 }
                                                             };
 
-        cbWantContinuousPresses.CheckedStateChanging += (s, e) =>
+        cbWantContinuousPresses.CheckedStateChanging += (_, _) =>
                                                         {
                                                             demo.WantContinuousButtonPressed = !demo.WantContinuousButtonPressed;
 
@@ -252,7 +252,7 @@ public class Mouse : Scenario
         };
         win.Add (label, appLog);
 
-        Application.MouseEvent += (sender, a) =>
+        Application.MouseEvent += (_, a) =>
                                   {
                                       int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
 
@@ -270,7 +270,7 @@ public class Mouse : Scenario
             X = Pos.Right (appLog) + 1,
             Y = Pos.Top (label)
         };
-        ObservableCollection<string> winLogList = new ();
+        ObservableCollection<string> winLogList = [];
 
         var winLog = new ListView
         {
@@ -283,7 +283,7 @@ public class Mouse : Scenario
         };
         win.Add (label, winLog);
 
-        clearButton.Accepting += (s, e) =>
+        clearButton.Accepting += (_, _) =>
                                  {
                                      appLogList.Clear ();
                                      appLog.SetSource (appLogList);
@@ -291,7 +291,7 @@ public class Mouse : Scenario
                                      winLog.SetSource (winLogList);
                                  };
 
-        win.MouseEvent += (sender, a) =>
+        win.MouseEvent += (_, a) =>
                           {
                               int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags);
 
@@ -302,12 +302,6 @@ public class Mouse : Scenario
                               }
                           };
 
-        win.MouseClick += (sender, a) =>
-                          {
-                              winLogList.Add ($"MouseClick: ({a.Position}) - {a.Flags} {count++}");
-                              winLog.MoveDown ();
-                          };
-
         Application.Run (win);
         win.Dispose ();
         Application.Shutdown ();
@@ -322,8 +316,8 @@ public class Mouse : Scenario
 
             Initialized += OnInitialized;
 
-            MouseLeave += (s, e) => { Text = "Leave"; };
-            MouseEnter += (s, e) => { Text = "Enter"; };
+            MouseLeave += (_, _) => { Text = "Leave"; };
+            MouseEnter += (_, _) => { Text = "Enter"; };
 
             return;
 

+ 102 - 107
Examples/UICatalog/Scenarios/ScrollBarDemo.cs

@@ -1,6 +1,4 @@
-using System;
-using System.Collections.ObjectModel;
-using System.Linq;
+using System.Collections.ObjectModel;
 
 namespace UICatalog.Scenarios;
 
@@ -18,7 +16,7 @@ public class ScrollBarDemo : Scenario
             Arrangement = ViewArrangement.Fixed
         };
 
-        var demoFrame = new FrameView ()
+        var demoFrame = new FrameView
         {
             Title = "Demo View",
             X = 0,
@@ -36,7 +34,7 @@ public class ScrollBarDemo : Scenario
             X = Pos.AnchorEnd () - 5,
             AutoShow = false,
             ScrollableContentSize = 100,
-            Height = Dim.Fill()
+            Height = Dim.Fill ()
         };
         demoFrame.Add (scrollBar);
 
@@ -45,7 +43,7 @@ public class ScrollBarDemo : Scenario
             X = Pos.AnchorEnd (),
             Width = 5,
             Height = Dim.Fill (),
-            SchemeName = "Error",
+            SchemeName = "Error"
         };
 
         demoFrame.Add (controlledList);
@@ -55,10 +53,9 @@ public class ScrollBarDemo : Scenario
 
         int GetMaxLabelWidth (int groupId)
         {
-            return demoFrame.SubViews.Max (
-                                           v =>
+            return demoFrame.SubViews.Max (v =>
                                            {
-                                               if (v.Y.Has<PosAlign> (out var pos) && pos.GroupId == groupId)
+                                               if (v.Y.Has<PosAlign> (out PosAlign pos) && pos.GroupId == groupId)
                                                {
                                                    return v.Text.GetColumns ();
                                                }
@@ -71,7 +68,7 @@ public class ScrollBarDemo : Scenario
         {
             Text = "_Width/Height:",
             TextAlignment = Alignment.End,
-            Y = Pos.Align (Alignment.Start, AlignmentModes.StartToEnd, groupId: 1),
+            Y = Pos.Align (Alignment.Start, AlignmentModes.StartToEnd, 1),
             Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblWidthHeight);
@@ -80,17 +77,17 @@ public class ScrollBarDemo : Scenario
         {
             Value = 1,
             X = Pos.Right (lblWidthHeight) + 1,
-            Y = Pos.Top (lblWidthHeight),
+            Y = Pos.Top (lblWidthHeight)
         };
         demoFrame.Add (scrollWidthHeight);
 
         scrollWidthHeight.ValueChanging += (s, e) =>
                                            {
                                                if (e.NewValue < 1
-                                                   || (e.NewValue
-                                                       > (scrollBar.Orientation == Orientation.Vertical
-                                                              ? scrollBar.SuperView?.GetContentSize ().Width
-                                                              : scrollBar.SuperView?.GetContentSize ().Height)))
+                                                   || e.NewValue
+                                                   > (scrollBar.Orientation == Orientation.Vertical
+                                                          ? scrollBar.SuperView?.GetContentSize ().Width
+                                                          : scrollBar.SuperView?.GetContentSize ().Height))
                                                {
                                                    // TODO: This must be handled in the ScrollSlider if Width and Height being virtual
                                                    e.Cancel = true;
@@ -108,7 +105,6 @@ public class ScrollBarDemo : Scenario
                                                }
                                            };
 
-
         var lblOrientationLabel = new Label
         {
             Text = "_Orientation:",
@@ -128,28 +124,26 @@ public class ScrollBarDemo : Scenario
         demoFrame.Add (osOrientation);
 
         osOrientation.ValueChanged += (s, e) =>
-                                             {
-
-                                                 if (osOrientation.Value == Orientation.Horizontal)
-                                                 {
-                                                     scrollBar.Orientation = Orientation.Vertical;
-                                                     scrollBar.X = Pos.AnchorEnd () - 5;
-                                                     scrollBar.Y = 0;
-                                                     scrollBar.Width = scrollWidthHeight.Value;
-                                                     scrollBar.Height = Dim.Fill ();
-                                                     controlledList.Visible = true;
-                                                 }
-                                                 else
-                                                 {
-                                                     scrollBar.Orientation = Orientation.Horizontal;
-                                                     scrollBar.X = 0;
-                                                     scrollBar.Y = Pos.AnchorEnd ();
-                                                     scrollBar.Height = scrollWidthHeight.Value;
-                                                     scrollBar.Width = Dim.Fill ();
-                                                     controlledList.Visible = false;
-
-                                                 }
-                                             };
+                                      {
+                                          if (osOrientation.Value == Orientation.Horizontal)
+                                          {
+                                              scrollBar.Orientation = Orientation.Vertical;
+                                              scrollBar.X = Pos.AnchorEnd () - 5;
+                                              scrollBar.Y = 0;
+                                              scrollBar.Width = scrollWidthHeight.Value;
+                                              scrollBar.Height = Dim.Fill ();
+                                              controlledList.Visible = true;
+                                          }
+                                          else
+                                          {
+                                              scrollBar.Orientation = Orientation.Horizontal;
+                                              scrollBar.X = 0;
+                                              scrollBar.Y = Pos.AnchorEnd ();
+                                              scrollBar.Height = scrollWidthHeight.Value;
+                                              scrollBar.Width = Dim.Fill ();
+                                              controlledList.Visible = false;
+                                          }
+                                      };
 
         var lblSize = new Label
         {
@@ -169,20 +163,24 @@ public class ScrollBarDemo : Scenario
         demoFrame.Add (scrollContentSize);
 
         scrollContentSize.ValueChanging += (s, e) =>
-                                    {
-                                        if (e.NewValue < 0)
-                                        {
-                                            e.Cancel = true;
+                                           {
+                                               if (e.NewValue < 0)
+                                               {
+                                                   e.Cancel = true;
 
-                                            return;
-                                        }
+                                                   return;
+                                               }
 
-                                        if (scrollBar.ScrollableContentSize != e.NewValue)
-                                        {
-                                            scrollBar.ScrollableContentSize = e.NewValue;
-                                            controlledList.SetSource (new ObservableCollection<string> (Enumerable.Range (0, scrollBar.ScrollableContentSize).Select (n => $"{n:00000}")));
-                                        }
-                                    };
+                                               if (scrollBar.ScrollableContentSize != e.NewValue)
+                                               {
+                                                   scrollBar.ScrollableContentSize = e.NewValue;
+
+                                                   controlledList.SetSource (
+                                                                             new ObservableCollection<string> (
+                                                                              Enumerable.Range (0, scrollBar.ScrollableContentSize)
+                                                                                        .Select (n => $"{n:00000}")));
+                                               }
+                                           };
 
         var lblVisibleContentSize = new Label
         {
@@ -202,20 +200,19 @@ public class ScrollBarDemo : Scenario
         demoFrame.Add (visibleContentSize);
 
         visibleContentSize.ValueChanging += (s, e) =>
-                                           {
-                                               if (e.NewValue < 0)
-                                               {
-                                                   e.Cancel = true;
-
-                                                   return;
-                                               }
+                                            {
+                                                if (e.NewValue < 0)
+                                                {
+                                                    e.Cancel = true;
 
-                                               if (scrollBar.VisibleContentSize != e.NewValue)
-                                               {
-                                                   scrollBar.VisibleContentSize = e.NewValue;
-                                               }
-                                           };
+                                                    return;
+                                                }
 
+                                                if (scrollBar.VisibleContentSize != e.NewValue)
+                                                {
+                                                    scrollBar.VisibleContentSize = e.NewValue;
+                                                }
+                                            };
 
         var lblPosition = new Label
         {
@@ -223,7 +220,6 @@ public class ScrollBarDemo : Scenario
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
             Width = Dim.Func (_ => GetMaxLabelWidth (1))
-
         };
         demoFrame.Add (lblPosition);
 
@@ -236,24 +232,24 @@ public class ScrollBarDemo : Scenario
         demoFrame.Add (scrollPosition);
 
         scrollPosition.ValueChanging += (s, e) =>
-                                               {
-                                                   if (e.NewValue < 0)
-                                                   {
-                                                       e.Cancel = true;
-
-                                                       return;
-                                                   }
-
-                                                   if (scrollBar.Position != e.NewValue)
-                                                   {
-                                                       scrollBar.Position = e.NewValue;
-                                                   }
-
-                                                   if (scrollBar.Position != e.NewValue)
-                                                   {
-                                                       e.Cancel = true;
-                                                   }
-                                               };
+                                        {
+                                            if (e.NewValue < 0)
+                                            {
+                                                e.Cancel = true;
+
+                                                return;
+                                            }
+
+                                            if (scrollBar.Position != e.NewValue)
+                                            {
+                                                scrollBar.Position = e.NewValue;
+                                            }
+
+                                            if (scrollBar.Position != e.NewValue)
+                                            {
+                                                e.Cancel = true;
+                                            }
+                                        };
 
         var lblOptions = new Label
         {
@@ -263,11 +259,12 @@ public class ScrollBarDemo : Scenario
             Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblOptions);
+
         var autoShow = new CheckBox
         {
             Y = Pos.Top (lblOptions),
             X = Pos.Right (lblOptions) + 1,
-            Text = $"_AutoShow",
+            Text = "_AutoShow",
             CheckedState = scrollBar.AutoShow ? CheckState.Checked : CheckState.UnChecked
         };
         autoShow.CheckedStateChanging += (s, e) => scrollBar.AutoShow = e.Result == CheckState.Checked;
@@ -296,9 +293,9 @@ public class ScrollBarDemo : Scenario
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
             Width = Dim.Func (_ => GetMaxLabelWidth (1))
-
         };
         demoFrame.Add (lblScrolled);
+
         Label scrolled = new ()
         {
             X = Pos.Right (lblScrolled) + 1,
@@ -347,43 +344,41 @@ public class ScrollBarDemo : Scenario
         void AppOnInitialized (object sender, EventArgs e)
         {
             scrollBar.ScrollableContentSizeChanged += (s, e) =>
-                                  {
-                                      eventLog.Log ($"SizeChanged: {e.Value}");
+                                                      {
+                                                          eventLog.Log ($"SizeChanged: {e.Value}");
 
-                                      if (scrollContentSize.Value != e.Value)
-                                      {
-                                          scrollContentSize.Value = e.Value;
-                                      }
-                                  };
+                                                          if (scrollContentSize.Value != e.Value)
+                                                          {
+                                                              scrollContentSize.Value = e.Value;
+                                                          }
+                                                      };
 
             scrollBar.SliderPositionChanged += (s, e) =>
-                                            {
-                                                eventLog.Log ($"SliderPositionChanged: {e.Value}");
-                                                eventLog.Log ($"  Position: {scrollBar.Position}");
-                                                scrollSliderPosition.Text = e.Value.ToString ();
-                                            };
+                                               {
+                                                   eventLog.Log ($"SliderPositionChanged: {e.Value}");
+                                                   eventLog.Log ($"  Position: {scrollBar.Position}");
+                                                   scrollSliderPosition.Text = e.Value.ToString ();
+                                               };
 
             scrollBar.Scrolled += (s, e) =>
-                               {
-                                   eventLog.Log ($"Scrolled: {e.Value}");
-                                   eventLog.Log ($"  SliderPosition: {scrollBar.GetSliderPosition ()}");
-                                   scrolled.Text = e.Value.ToString ();
-                               };
+                                  {
+                                      eventLog.Log ($"Scrolled: {e.Value}");
+                                      eventLog.Log ($"  SliderPosition: {scrollBar.GetSliderPosition ()}");
+                                      scrolled.Text = e.Value.ToString ();
+                                  };
 
             scrollBar.PositionChanged += (s, e) =>
-                                             {
-                                                 eventLog.Log ($"PositionChanged: {e.Value}");
-                                                 scrollPosition.Value = e.Value;
-                                                 controlledList.Viewport = controlledList.Viewport with { Y = e.Value };
-                                             };
-
+                                         {
+                                             eventLog.Log ($"PositionChanged: {e.Value}");
+                                             scrollPosition.Value = e.Value;
+                                             controlledList.Viewport = controlledList.Viewport with { Y = e.Value };
+                                         };
 
             controlledList.ViewportChanged += (s, e) =>
                                               {
                                                   eventLog.Log ($"ViewportChanged: {e.NewViewport}");
                                                   scrollBar.Position = e.NewViewport.Y;
                                               };
-
         }
 
         Application.Run (app);

+ 29 - 23
Examples/UICatalog/Scenarios/TableEditor.cs

@@ -610,29 +610,35 @@ public class TableEditor : Scenario
         };
 
         // if user clicks the mouse in TableView
-        _tableView!.MouseClick += (s, e) =>
-                                  {
-                                      if (_currentTable == null)
-                                      {
-                                          return;
-                                      }
-
-                                      _tableView!.ScreenToCell (e.Position, out int? clickedCol);
-
-                                      if (clickedCol != null)
-                                      {
-                                          if (e.Flags.HasFlag (MouseFlags.Button1Clicked))
-                                          {
-                                              // left click in a header
-                                              SortColumn (clickedCol.Value);
-                                          }
-                                          else if (e.Flags.HasFlag (MouseFlags.Button3Clicked))
-                                          {
-                                              // right click in a header
-                                              ShowHeaderContextMenu (clickedCol.Value, e);
-                                          }
-                                      }
-                                  };
+        _tableView!.Selecting += (s, e) =>
+                                 {
+                                     if (_currentTable == null)
+                                     {
+                                         return;
+                                     }
+
+                                     // Only handle mouse clicks
+                                     if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+                                     {
+                                         return;
+                                     }
+
+                                     _tableView!.ScreenToCell (mouseArgs.Position, out int? clickedCol);
+
+                                     if (clickedCol != null)
+                                     {
+                                         if (mouseArgs.Flags.HasFlag (MouseFlags.Button1Clicked))
+                                         {
+                                             // left click in a header
+                                             SortColumn (clickedCol.Value);
+                                         }
+                                         else if (mouseArgs.Flags.HasFlag (MouseFlags.Button3Clicked))
+                                         {
+                                             // right click in a header
+                                             ShowHeaderContextMenu (clickedCol.Value, mouseArgs);
+                                         }
+                                     }
+                                 };
 
         _tableView!.KeyBindings.ReplaceCommands (Key.Space, Command.Accept);
 

+ 94 - 105
Examples/UICatalog/Scenarios/TextAlignmentAndDirection.cs

@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Text;
 
 namespace UICatalog.Scenarios;
 
@@ -9,12 +6,11 @@ namespace UICatalog.Scenarios;
 [ScenarioCategory ("Text and Formatting")]
 public class TextAlignmentAndDirection : Scenario
 {
-
     internal class AlignmentAndDirectionView : View
     {
         public AlignmentAndDirectionView ()
         {
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent;
+            ViewportSettings = ViewportSettingsFlags.Transparent;
             BorderStyle = LineStyle.Dotted;
         }
     }
@@ -30,15 +26,15 @@ public class TextAlignmentAndDirection : Scenario
 
         var txt = $"Hello World{Environment.NewLine}HELLO WORLD{Environment.NewLine}世界 您好";
 
-        SchemeManager.AddScheme ("TextAlignmentAndDirection1", new Scheme { Normal = new (Color.Black, Color.Gray) });
-        SchemeManager.AddScheme ("TextAlignmentAndDirection2", new Scheme { Normal = new (Color.Black, Color.DarkGray) });
+        SchemeManager.AddScheme ("TextAlignmentAndDirection1", new () { Normal = new (Color.Black, Color.Gray) });
+        SchemeManager.AddScheme ("TextAlignmentAndDirection2", new () { Normal = new (Color.Black, Color.DarkGray) });
 
-        List<View> singleLineLabels = new (); // single line
-        List<View> multiLineLabels = new (); // multi line
+        List<View> singleLineLabels = []; // single line
+        List<View> multiLineLabels = []; // multi line
 
-        // Horizontal Single-Line 
+        // Horizontal Single-Line
 
-        var labelHL = new Label
+        Label labelHL = new ()
         {
             X = 0,
             Y = 0,
@@ -46,10 +42,10 @@ public class TextAlignmentAndDirection : Scenario
             Height = 1,
             TextAlignment = Alignment.End,
             SchemeName = "Dialog",
-            Text = "Start",
+            Text = "Start"
         };
 
-        var labelHC = new Label
+        Label labelHC = new ()
         {
             X = 0,
             Y = 1,
@@ -60,7 +56,7 @@ public class TextAlignmentAndDirection : Scenario
             Text = "Center"
         };
 
-        var labelHR = new Label
+        Label labelHR = new ()
         {
             X = 0,
             Y = 2,
@@ -71,7 +67,7 @@ public class TextAlignmentAndDirection : Scenario
             Text = "End"
         };
 
-        var labelHJ = new Label
+        Label labelHJ = new ()
         {
             X = 0,
             Y = 3,
@@ -82,7 +78,7 @@ public class TextAlignmentAndDirection : Scenario
             Text = "Fill"
         };
 
-        var txtLabelHL = new View
+        View txtLabelHL = new ()
         {
             X = Pos.Right (labelHL) + 1,
             Y = Pos.Y (labelHL),
@@ -91,10 +87,10 @@ public class TextAlignmentAndDirection : Scenario
             SchemeName = "TextAlignmentAndDirection1",
             TextAlignment = Alignment.Start,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
 
-        var txtLabelHC = new View
+        View txtLabelHC = new ()
         {
             X = Pos.Right (labelHC) + 1,
             Y = Pos.Y (labelHC),
@@ -103,10 +99,10 @@ public class TextAlignmentAndDirection : Scenario
             SchemeName = "TextAlignmentAndDirection2",
             TextAlignment = Alignment.Center,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
 
-        var txtLabelHR = new View
+        View txtLabelHR = new ()
         {
             X = Pos.Right (labelHR) + 1,
             Y = Pos.Y (labelHR),
@@ -115,10 +111,10 @@ public class TextAlignmentAndDirection : Scenario
             SchemeName = "TextAlignmentAndDirection1",
             TextAlignment = Alignment.End,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
 
-        var txtLabelHJ = new View
+        View txtLabelHJ = new ()
         {
             X = Pos.Right (labelHJ) + 1,
             Y = Pos.Y (labelHJ),
@@ -127,7 +123,7 @@ public class TextAlignmentAndDirection : Scenario
             SchemeName = "TextAlignmentAndDirection2",
             TextAlignment = Alignment.Fill,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
 
         singleLineLabels.Add (txtLabelHL);
@@ -146,7 +142,7 @@ public class TextAlignmentAndDirection : Scenario
 
         // Vertical Single-Line
 
-        var labelVT = new Label
+        Label labelVT = new ()
         {
             X = Pos.AnchorEnd () - 6,
             Y = 0,
@@ -159,7 +155,7 @@ public class TextAlignmentAndDirection : Scenario
         };
         labelVT.TextFormatter.WordWrap = false;
 
-        var labelVM = new Label
+        Label labelVM = new ()
         {
             X = Pos.AnchorEnd () - 4,
             Y = 0,
@@ -172,7 +168,7 @@ public class TextAlignmentAndDirection : Scenario
         };
         labelVM.TextFormatter.WordWrap = false;
 
-        var labelVB = new Label
+        Label labelVB = new ()
         {
             X = Pos.AnchorEnd () - 2,
             Y = 0,
@@ -185,7 +181,7 @@ public class TextAlignmentAndDirection : Scenario
         };
         labelVB.TextFormatter.WordWrap = false;
 
-        var labelVJ = new Label
+        Label labelVJ = new ()
         {
             X = Pos.AnchorEnd (),
             Y = 0,
@@ -198,7 +194,7 @@ public class TextAlignmentAndDirection : Scenario
         };
         labelVJ.TextFormatter.WordWrap = false;
 
-        var txtLabelVT = new View
+        View txtLabelVT = new ()
         {
             X = Pos.X (labelVT),
             Y = Pos.Bottom (labelVT) + 1,
@@ -208,11 +204,11 @@ public class TextAlignmentAndDirection : Scenario
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.Start,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
         txtLabelVT.TextFormatter.WordWrap = false;
 
-        var txtLabelVM = new View
+        View txtLabelVM = new ()
         {
             X = Pos.X (labelVM),
             Y = Pos.Bottom (labelVM) + 1,
@@ -222,11 +218,11 @@ public class TextAlignmentAndDirection : Scenario
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.Center,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
         txtLabelVM.TextFormatter.WordWrap = false;
 
-        var txtLabelVB = new View
+        View txtLabelVB = new ()
         {
             X = Pos.X (labelVB),
             Y = Pos.Bottom (labelVB) + 1,
@@ -236,11 +232,11 @@ public class TextAlignmentAndDirection : Scenario
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.End,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
         txtLabelVB.TextFormatter.WordWrap = false;
 
-        var txtLabelVJ = new View
+        View txtLabelVJ = new ()
         {
             X = Pos.X (labelVJ),
             Y = Pos.Bottom (labelVJ) + 1,
@@ -250,7 +246,7 @@ public class TextAlignmentAndDirection : Scenario
             TextDirection = TextDirection.TopBottom_LeftRight,
             VerticalTextAlignment = Alignment.Fill,
             Text = txt,
-            ViewportSettings = Terminal.Gui.ViewBase.ViewportSettingsFlags.Transparent
+            ViewportSettings = ViewportSettingsFlags.Transparent
         };
         txtLabelVJ.TextFormatter.WordWrap = false;
 
@@ -270,7 +266,7 @@ public class TextAlignmentAndDirection : Scenario
 
         // Multi-Line
 
-        var container = new View
+        View container = new ()
         {
             X = 0,
             Y = Pos.Bottom (txtLabelHJ),
@@ -280,7 +276,7 @@ public class TextAlignmentAndDirection : Scenario
             //SchemeName = "TextAlignmentAndDirection2"
         };
 
-        var txtLabelTL = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelTL = new ()
         {
             X = 0,
             Y = 1,
@@ -289,11 +285,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.Start,
             VerticalTextAlignment = Alignment.Start,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelTL.TextFormatter.MultiLine = true;
 
-        var txtLabelTC = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelTC = new ()
         {
             X = Pos.Right (txtLabelTL),
             Y = 1,
@@ -302,11 +298,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.Center,
             VerticalTextAlignment = Alignment.Start,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelTC.TextFormatter.MultiLine = true;
 
-        var txtLabelTR = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelTR = new ()
         {
             X = Pos.Right (txtLabelTC),
             Y = 1,
@@ -315,11 +311,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.End,
             VerticalTextAlignment = Alignment.Start,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelTR.TextFormatter.MultiLine = true;
 
-        var txtLabelML = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelML = new ()
         {
             X = Pos.X (txtLabelTL),
             Y = Pos.Bottom (txtLabelTL),
@@ -328,11 +324,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.Start,
             VerticalTextAlignment = Alignment.Center,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelML.TextFormatter.MultiLine = true;
 
-        var txtLabelMC = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelMC = new ()
         {
             X = Pos.X (txtLabelTC),
             Y = Pos.Bottom (txtLabelTC),
@@ -341,11 +337,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.Center,
             VerticalTextAlignment = Alignment.Center,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelMC.TextFormatter.MultiLine = true;
 
-        var txtLabelMR = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelMR = new ()
         {
             X = Pos.X (txtLabelTR),
             Y = Pos.Bottom (txtLabelTR),
@@ -354,11 +350,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.End,
             VerticalTextAlignment = Alignment.Center,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelMR.TextFormatter.MultiLine = true;
 
-        var txtLabelBL = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelBL = new ()
         {
             X = Pos.X (txtLabelML),
             Y = Pos.Bottom (txtLabelML),
@@ -367,11 +363,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.Start,
             VerticalTextAlignment = Alignment.End,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelBL.TextFormatter.MultiLine = true;
 
-        var txtLabelBC = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelBC = new ()
         {
             X = Pos.X (txtLabelMC),
             Y = Pos.Bottom (txtLabelMC),
@@ -380,11 +376,11 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.Center,
             VerticalTextAlignment = Alignment.End,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelBC.TextFormatter.MultiLine = true;
 
-        var txtLabelBR = new AlignmentAndDirectionView
+        AlignmentAndDirectionView txtLabelBR = new ()
         {
             X = Pos.X (txtLabelMR),
             Y = Pos.Bottom (txtLabelMR),
@@ -393,7 +389,7 @@ public class TextAlignmentAndDirection : Scenario
             TextAlignment = Alignment.End,
             VerticalTextAlignment = Alignment.End,
             SchemeName = "TextAlignmentAndDirection1",
-            Text = txt,
+            Text = txt
         };
         txtLabelBR.TextFormatter.MultiLine = true;
 
@@ -429,7 +425,7 @@ public class TextAlignmentAndDirection : Scenario
 
         // Edit Text
 
-        var label = new Label
+        Label label = new ()
         {
             X = 1,
             Y = Pos.Bottom (container) + 1,
@@ -438,7 +434,7 @@ public class TextAlignmentAndDirection : Scenario
             Text = "Edit Text:"
         };
 
-        var editText = new TextView
+        TextView editText = new ()
         {
             X = Pos.Right (label) + 1,
             Y = Pos.Top (label),
@@ -447,19 +443,6 @@ public class TextAlignmentAndDirection : Scenario
             Text = txt
         };
 
-        editText.MouseClick += (s, m) =>
-                               {
-                                   foreach (View v in singleLineLabels)
-                                   {
-                                       v.Text = editText.Text;
-                                   }
-
-                                   foreach (View v in multiLineLabels)
-                                   {
-                                       v.Text = editText.Text;
-                                   }
-                               };
-
         app.KeyUp += (s, m) =>
                      {
                          foreach (View v in singleLineLabels)
@@ -479,7 +462,7 @@ public class TextAlignmentAndDirection : Scenario
 
         // JUSTIFY CHECKBOX
 
-        var justifyCheckbox = new CheckBox
+        CheckBox justifyCheckbox = new ()
         {
             X = Pos.Right (container) + 1,
             Y = Pos.Y (container) + 1,
@@ -492,7 +475,7 @@ public class TextAlignmentAndDirection : Scenario
 
         // JUSTIFY OPTIONS
 
-        var justifyOptions = new OptionSelector
+        OptionSelector justifyOptions = new ()
         {
             X = Pos.Left (justifyCheckbox) + 1,
             Y = Pos.Y (justifyCheckbox) + 1,
@@ -509,7 +492,7 @@ public class TextAlignmentAndDirection : Scenario
 
         // WRAP CHECKBOX
 
-        var wrapCheckbox = new CheckBox
+        CheckBox wrapCheckbox = new ()
         {
             X = Pos.Right (container) + 1,
             Y = Pos.Bottom (justifyOptions),
@@ -520,28 +503,28 @@ public class TextAlignmentAndDirection : Scenario
         wrapCheckbox.CheckedState = wrapCheckbox.TextFormatter.WordWrap ? CheckState.Checked : CheckState.UnChecked;
 
         wrapCheckbox.CheckedStateChanging += (s, e) =>
-                                {
-                                    if (e.Result == CheckState.Checked)
-                                    {
-                                        foreach (View t in multiLineLabels)
-                                        {
-                                            t.TextFormatter.WordWrap = false;
-                                        }
-                                    }
-                                    else
-                                    {
-                                        foreach (View t in multiLineLabels)
-                                        {
-                                            t.TextFormatter.WordWrap = true;
-                                        }
-                                    }
-                                };
+                                             {
+                                                 if (e.Result == CheckState.Checked)
+                                                 {
+                                                     foreach (View t in multiLineLabels)
+                                                     {
+                                                         t.TextFormatter.WordWrap = false;
+                                                     }
+                                                 }
+                                                 else
+                                                 {
+                                                     foreach (View t in multiLineLabels)
+                                                     {
+                                                         t.TextFormatter.WordWrap = true;
+                                                     }
+                                                 }
+                                             };
 
         app.Add (wrapCheckbox);
 
         List<TextDirection> directionsEnum = Enum.GetValues (typeof (TextDirection)).Cast<TextDirection> ().ToList ();
 
-        var directionOptions = new OptionSelector
+        OptionSelector directionOptions = new ()
         {
             X = Pos.Right (container) + 1,
             Y = Pos.Bottom (wrapCheckbox) + 1,
@@ -552,24 +535,24 @@ public class TextAlignmentAndDirection : Scenario
         };
 
         directionOptions.ValueChanged += (s, ev) =>
-                                                {
-                                                    bool justChecked = justifyCheckbox.CheckedState == CheckState.Checked;
+                                         {
+                                             bool justChecked = justifyCheckbox.CheckedState == CheckState.Checked;
 
-                                                    if (justChecked)
-                                                    {
-                                                        ToggleJustify (true);
-                                                    }
+                                             if (justChecked)
+                                             {
+                                                 ToggleJustify (true);
+                                             }
 
-                                                    foreach (View v in multiLineLabels.Where (v => ev.Value is { }))
-                                                    {
-                                                        v.TextDirection = (TextDirection)ev.Value!.Value;
-                                                    }
+                                             foreach (View v in multiLineLabels.Where (v => ev.Value is { }))
+                                             {
+                                                 v.TextDirection = (TextDirection)ev.Value!.Value;
+                                             }
 
-                                                    if (justChecked)
-                                                    {
-                                                        ToggleJustify (false);
-                                                    }
-                                                };
+                                             if (justChecked)
+                                             {
+                                                 ToggleJustify (false);
+                                             }
+                                         };
 
         app.Add (directionOptions);
 
@@ -617,14 +600,17 @@ public class TextAlignmentAndDirection : Scenario
                             case 0:
                                 t.VerticalTextAlignment = Alignment.Fill;
                                 t.TextAlignment = data!.h;
+
                                 break;
                             case 1:
                                 t.VerticalTextAlignment = data!.v;
                                 t.TextAlignment = Alignment.Fill;
+
                                 break;
                             case 2:
                                 t.VerticalTextAlignment = Alignment.Fill;
                                 t.TextAlignment = Alignment.Fill;
+
                                 break;
                         }
                     }
@@ -635,14 +621,17 @@ public class TextAlignmentAndDirection : Scenario
                             case 0:
                                 t.TextAlignment = Alignment.Fill;
                                 t.VerticalTextAlignment = data!.v;
+
                                 break;
                             case 1:
                                 t.TextAlignment = data!.h;
                                 t.VerticalTextAlignment = Alignment.Fill;
+
                                 break;
                             case 2:
                                 t.TextAlignment = Alignment.Fill;
                                 t.VerticalTextAlignment = Alignment.Fill;
+
                                 break;
                         }
                     }

+ 12 - 6
Examples/UICatalog/Scenarios/TreeViewFileSystem.cs

@@ -60,7 +60,7 @@ public class TreeViewFileSystem : Scenario
         };
 
         win.Add (_detailsFrame);
-        _treeViewFiles.MouseClick += TreeViewFiles_MouseClick;
+        _treeViewFiles.Selecting += TreeViewFiles_Selecting;
         _treeViewFiles.KeyDown += TreeViewFiles_KeyPress;
         _treeViewFiles.SelectionChanged += TreeViewFiles_SelectionChanged;
 
@@ -556,17 +556,23 @@ public class TreeViewFileSystem : Scenario
         }
     }
 
-    private void TreeViewFiles_MouseClick (object? sender, MouseEventArgs obj)
+    private void TreeViewFiles_Selecting (object? sender, CommandEventArgs e)
     {
         if (_treeViewFiles is null)
         {
             return;
         }
 
+        // Only handle mouse clicks
+        if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            return;
+        }
+
         // if user right clicks
-        if (obj.Flags.HasFlag (MouseFlags.Button3Clicked))
+        if (mouseArgs.Flags.HasFlag (MouseFlags.Button3Clicked))
         {
-            IFileSystemInfo? rightClicked = _treeViewFiles.GetObjectOnRow (obj.Position.Y);
+            IFileSystemInfo? rightClicked = _treeViewFiles.GetObjectOnRow (mouseArgs.Position.Y);
 
             // nothing was clicked
             if (rightClicked is null)
@@ -576,8 +582,8 @@ public class TreeViewFileSystem : Scenario
 
             ShowContextMenu (
                              new (
-                                  obj.Position.X + _treeViewFiles.Frame.X,
-                                  obj.Position.Y + _treeViewFiles.Frame.Y + 2
+                                  mouseArgs.Position.X + _treeViewFiles.Frame.X,
+                                  mouseArgs.Position.Y + _treeViewFiles.Frame.Y + 2
                                  ),
                              rightClicked
                             );

+ 10 - 9
Examples/UICatalog/Scenarios/ViewExperiments.cs

@@ -86,18 +86,19 @@ public class ViewExperiments : Scenario
             //App?.Popover!.Visible = true;
         }
 
-        testFrame.MouseClick += TestFrameOnMouseClick;
-
-        void TestFrameOnMouseClick (object sender, MouseEventArgs e)
+        testFrame.Selecting += (sender, e) =>
         {
-            if (e.Flags == MouseFlags.Button3Clicked)
+            if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
             {
-                popoverView.X = e.ScreenPosition.X;
-                popoverView.Y = e.ScreenPosition.Y;
-                //App?.Popover = popoverView;
-                //App?.Popover!.Visible = true;
+                if (mouseArgs.Flags == MouseFlags.Button3Clicked)
+                {
+                    popoverView.X = mouseArgs.ScreenPosition.X;
+                    popoverView.Y = mouseArgs.ScreenPosition.Y;
+                    //App?.Popover = popoverView;
+                    //App?.Popover!.Visible = true;
+                }
             }
-        }
+        };
 
         testFrame.Add (button);
 

+ 1 - 4
Terminal.Gui/Input/Mouse/MouseEventArgs.cs

@@ -4,10 +4,7 @@ using System.ComponentModel;
 namespace Terminal.Gui.Input;
 
 /// <summary>
-///     Specifies the event arguments for <see cref="MouseEventArgs"/>. This is a higher-level construct than
-///     the wrapped <see cref="MouseEventArgs"/> class and is used for the events defined on
-///     <see cref="View"/> and subclasses
-///     of View (e.g. <see cref="View.MouseEnter"/> and <see cref="View.MouseClick"/>).
+///     Specifies the event arguments for <see cref="MouseEventArgs"/>.
 /// </summary>
 public class MouseEventArgs : HandledEventArgs
 {

+ 10 - 89
Terminal.Gui/ViewBase/View.Mouse.cs

@@ -236,10 +236,6 @@ public partial class View // Mouse APIs
     ///         A view must be both enabled and visible to receive mouse events.
     ///     </para>
     ///     <para>
-    ///         This method raises <see cref="RaiseMouseEvent"/>/<see cref="MouseEvent"/>; if not handled, and one of the
-    ///         mouse buttons was clicked, the <see cref="RaiseMouseClickEvent"/>/<see cref="MouseClick"/> event will be raised
-    ///     </para>
-    ///     <para>
     ///         If <see cref="WantContinuousButtonPressed"/> is <see langword="true"/>, and the user presses and holds the
     ///         mouse button, <see cref="NewMouseEvent"/> will be repeatedly called with the same <see cref="MouseFlags"/> for
     ///         as long as the mouse button remains pressed.
@@ -291,13 +287,6 @@ public partial class View // Mouse APIs
             }
         }
 
-        // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent, and
-        // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked
-        if (mouseEvent.IsSingleDoubleOrTripleClicked)
-        {
-            return RaiseMouseClickEvent (mouseEvent);
-        }
-
         if (mouseEvent.IsWheel)
         {
             return RaiseMouseWheelEvent (mouseEvent);
@@ -333,6 +322,11 @@ public partial class View // Mouse APIs
 
         MouseEvent?.Invoke (this, mouseEvent);
 
+        if (!mouseEvent.Handled)
+        {
+            mouseEvent.Handled = InvokeCommandsBoundToMouse (mouseEvent) == true;
+        }
+
         return mouseEvent.Handled;
     }
 
@@ -356,7 +350,7 @@ public partial class View // Mouse APIs
 
     #endregion Low Level Mouse Events
 
-    #region Mouse Pressed Events
+    #region WhenGrabbed Handlers
 
     /// <summary>
     ///     INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the released event
@@ -450,81 +444,6 @@ public partial class View // Mouse APIs
         return false;
     }
 
-    #endregion Mouse Pressed Events
-
-    #region Mouse Click Events
-
-    /// <summary>Raises the <see cref="OnMouseClick"/>/<see cref="MouseClick"/> event.</summary>
-    /// <remarks>
-    ///     <para>
-    ///         Called when the mouse is either clicked or double-clicked.
-    ///     </para>
-    ///     <para>
-    ///         If <see cref="WantContinuousButtonPressed"/> is <see langword="true"/>, will be invoked on every mouse event
-    ///         where
-    ///         the mouse button is pressed.
-    ///     </para>
-    /// </remarks>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    protected bool RaiseMouseClickEvent (MouseEventArgs args)
-    {
-        // Pre-conditions
-        if (!Enabled)
-        {
-            // QUESTION: Is this right? Should a disabled view eat mouse clicks?
-            return args.Handled = false;
-        }
-
-        // Cancellable event
-        if (OnMouseClick (args) || args.Handled)
-        {
-            return args.Handled;
-        }
-
-        MouseClick?.Invoke (this, args);
-
-        if (args.Handled)
-        {
-            return true;
-        }
-
-        // Post-conditions
-
-        // By default, this will raise Selecting/OnSelecting - Subclasses can override this via AddCommand (Command.Select ...).
-        args.Handled = InvokeCommandsBoundToMouse (args) == true;
-
-        return args.Handled;
-    }
-
-    /// <summary>
-    ///     Called when a mouse click occurs. Check <see cref="MouseEventArgs.Flags"/> to see which button was clicked.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         Called when the mouse is either clicked or double-clicked.
-    ///     </para>
-    ///     <para>
-    ///         If <see cref="WantContinuousButtonPressed"/> is <see langword="true"/>, will be called on every mouse event
-    ///         where
-    ///         the mouse button is pressed.
-    ///     </para>
-    /// </remarks>
-    /// <param name="args"></param>
-    /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
-    protected virtual bool OnMouseClick (MouseEventArgs args) { return false; }
-
-    /// <summary>Raised when a mouse click occurs.</summary>
-    /// <remarks>
-    ///     <para>
-    ///         Raised when the mouse is either clicked or double-clicked.
-    ///     </para>
-    ///     <para>
-    ///         If <see cref="WantContinuousButtonPressed"/> is <see langword="true"/>, will be raised on every mouse event
-    ///         where
-    ///         the mouse button is pressed.
-    ///     </para>
-    /// </remarks>
-    public event EventHandler<MouseEventArgs>? MouseClick;
 
     /// <summary>
     ///     INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the click event
@@ -553,7 +472,8 @@ public partial class View // Mouse APIs
             // If mouse is still in bounds, generate a click
             if (!WantMousePositionReports && Viewport.Contains (mouseEvent.Position))
             {
-                return RaiseMouseClickEvent (mouseEvent);
+                // By default, this will raise Selecting/OnSelecting - Subclasses can override this via AddCommand (Command.Select ...).
+                mouseEvent.Handled = InvokeCommandsBoundToMouse (mouseEvent) == true;
             }
 
             return mouseEvent.Handled = true;
@@ -562,7 +482,8 @@ public partial class View // Mouse APIs
         return false;
     }
 
-    #endregion Mouse Clicked Events
+
+    #endregion WhenGrabbed Handlers
 
     #region Mouse Wheel Events
 

+ 8 - 11
Terminal.Gui/Views/Button.cs

@@ -75,8 +75,15 @@ public class Button : View, IDesignable
         KeyBindings.Remove (Key.Enter);
         KeyBindings.Add (Key.Enter, Command.HotKey);
 
+        // Replace default Select binding with HotKey for mouse clicks
+        MouseBindings.Clear ();
+        MouseBindings.Add (MouseFlags.Button1Clicked, Command.HotKey);
+        MouseBindings.Add (MouseFlags.Button2Clicked, Command.HotKey);
+        MouseBindings.Add (MouseFlags.Button3Clicked, Command.HotKey);
+        MouseBindings.Add (MouseFlags.Button4Clicked, Command.HotKey);
+        MouseBindings.Add (MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl, Command.HotKey);
+
         TitleChanged += Button_TitleChanged;
-        MouseClick += Button_MouseClick;
 
         base.ShadowStyle = DefaultShadow;
         HighlightStates = DefaultHighlightStates;
@@ -115,16 +122,6 @@ public class Button : View, IDesignable
 
         return false;
     }
-    private void Button_MouseClick (object sender, MouseEventArgs e)
-    {
-        if (e.Handled)
-        {
-            return;
-        }
-
-        // TODO: With https://github.com/gui-cs/Terminal.Gui/issues/3778 we won't have to pass data:
-        e.Handled = InvokeCommand<KeyBinding> (Command.HotKey, new KeyBinding ([Command.HotKey], this, data: null)) == true;
-    }
 
     private void Button_TitleChanged (object sender, EventArgs<string> e)
     {

+ 14 - 8
Terminal.Gui/Views/FileDialogs/FileDialog.cs

@@ -195,7 +195,7 @@ public class FileDialog : Dialog, IDesignable
         };
         _tableView.CollectionNavigator = new FileDialogCollectionNavigator (this, _tableView);
         _tableView.KeyBindings.ReplaceCommands (Key.Space, Command.Select);
-        _tableView.MouseClick += OnTableViewMouseClick;
+        _tableView.Selecting += OnTableViewSelecting;
         Style.TableStyle = _tableView.Style;
 
         ColumnStyle nameStyle = Style.TableStyle.GetOrCreateColumnStyle (0);
@@ -1046,29 +1046,35 @@ public class FileDialog : Dialog, IDesignable
         }
     }
 
-    private void OnTableViewMouseClick (object? sender, MouseEventArgs e)
+    private void OnTableViewSelecting (object? sender, CommandEventArgs e)
     {
-        Point? clickedCell = _tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? clickedCol);
+        // Only handle mouse clicks, not keyboard selections
+        if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            return;
+        }
+
+        Point? clickedCell = _tableView.ScreenToCell (mouseArgs.Position.X, mouseArgs.Position.Y, out int? clickedCol);
 
         if (clickedCol is { })
         {
-            if (e.Flags.HasFlag (MouseFlags.Button1Clicked))
+            if (mouseArgs.Flags.HasFlag (MouseFlags.Button1Clicked))
             {
                 // left click in a header
                 SortColumn (clickedCol.Value);
             }
-            else if (e.Flags.HasFlag (MouseFlags.Button3Clicked))
+            else if (mouseArgs.Flags.HasFlag (MouseFlags.Button3Clicked))
             {
                 // right click in a header
-                ShowHeaderContextMenu (clickedCol.Value, e);
+                ShowHeaderContextMenu (clickedCol.Value, mouseArgs);
             }
         }
         else
         {
-            if (clickedCell is { } && e.Flags.HasFlag (MouseFlags.Button3Clicked))
+            if (clickedCell is { } && mouseArgs.Flags.HasFlag (MouseFlags.Button3Clicked))
             {
                 // right click in rest of table
-                ShowCellContextMenu (clickedCell, e);
+                ShowCellContextMenu (clickedCell, mouseArgs);
             }
         }
     }

+ 12 - 9
Terminal.Gui/Views/Label.cs

@@ -27,15 +27,6 @@ public class Label : View, IDesignable
         AddCommand (Command.HotKey, InvokeHotKeyOnNextPeer!);
 
         TitleChanged += Label_TitleChanged;
-        MouseClick += Label_MouseClick;
-    }
-
-    private void Label_MouseClick (object? sender, MouseEventArgs e)
-    {
-        if (!CanFocus)
-        {
-            e.Handled = InvokeCommand<KeyBinding> (Command.HotKey, new ([Command.HotKey], this, this)) == true;
-        }
     }
 
     private void Label_TitleChanged (object? sender, EventArgs<string> e)
@@ -89,6 +80,18 @@ public class Label : View, IDesignable
         return false;
     }
 
+    /// <inheritdoc/>
+    protected override bool OnSelecting (CommandEventArgs args)
+    {
+        // If Label can't focus and is clicked, invoke HotKey on next peer
+        if (!CanFocus)
+        {
+            return InvokeCommand (Command.HotKey, args.Context) == true;
+        }
+
+        return base.OnSelecting (args);
+    }
+
     /// <inheritdoc/>
     bool IDesignable.EnableForDesign ()
     {

+ 11 - 5
Terminal.Gui/Views/ScrollBar/ScrollBar.cs

@@ -517,12 +517,18 @@ public class ScrollBar : View, IOrientation, IDesignable
 
     // TODO: Change this to work OnMouseEvent with continuouse press and grab so it's continous.
     /// <inheritdoc/>
-    protected override bool OnMouseClick (MouseEventArgs args)
+    protected override bool OnSelecting (CommandEventArgs args)
     {
+        // Only handle mouse clicks
+        if (args.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            return base.OnSelecting (args);
+        }
+
         // Check if the mouse click is a single click
-        if (!args.IsSingleClicked)
+        if (!mouseArgs.IsSingleClicked)
         {
-            return false;
+            return base.OnSelecting (args);
         }
 
         int sliderCenter;
@@ -531,12 +537,12 @@ public class ScrollBar : View, IOrientation, IDesignable
         if (Orientation == Orientation.Vertical)
         {
             sliderCenter = 1 + _slider.Frame.Y + _slider.Frame.Height / 2;
-            distanceFromCenter = args.Position.Y - sliderCenter;
+            distanceFromCenter = mouseArgs.Position.Y - sliderCenter;
         }
         else
         {
             sliderCenter = 1 + _slider.Frame.X + _slider.Frame.Width / 2;
-            distanceFromCenter = args.Position.X - sliderCenter;
+            distanceFromCenter = mouseArgs.Position.X - sliderCenter;
         }
 
 #if PROPORTIONAL_SCROLL_JUMP

+ 8 - 2
Terminal.Gui/Views/TabView/TabRow.cs

@@ -24,7 +24,10 @@ internal class TabRow : View
             Visible = false,
             Text = Glyphs.RightArrow.ToString ()
         };
-        _rightScrollIndicator.MouseClick += _host.Tab_MouseClick!;
+        _rightScrollIndicator.Selecting += (s, e) =>
+        {
+            _host.Tab_Selecting (s, e);
+        };
 
         _leftScrollIndicator = new View
         {
@@ -34,7 +37,10 @@ internal class TabRow : View
             Visible = false,
             Text = Glyphs.LeftArrow.ToString ()
         };
-        _leftScrollIndicator.MouseClick += _host.Tab_MouseClick!;
+        _leftScrollIndicator.Selecting += (s, e) =>
+        {
+            _host.Tab_Selecting (s, e);
+        };
 
         Add (_rightScrollIndicator, _leftScrollIndicator);
     }

+ 13 - 10
Terminal.Gui/Views/TabView/TabView.cs

@@ -563,8 +563,8 @@ public class TabView : View
             if (maxWidth == 0)
             {
                 tab.Visible = true;
-                tab.MouseClick += Tab_MouseClick!;
-                tab.Border!.MouseClick += Tab_MouseClick!;
+                tab.Selecting += Tab_Selecting!;
+                tab.Border!.Selecting += Tab_Selecting!;
 
                 yield return tab;
 
@@ -594,8 +594,8 @@ public class TabView : View
 
             // there is enough space!
             tab.Visible = true;
-            tab.MouseClick += Tab_MouseClick!;
-            tab.Border!.MouseClick += Tab_MouseClick!;
+            tab.Selecting += Tab_Selecting!;
+            tab.Border!.Selecting += Tab_Selecting!;
 
             yield return tab;
 
@@ -636,9 +636,12 @@ public class TabView : View
         return Style.ShowTopLine ? 3 : 2;
     }
 
-    internal void Tab_MouseClick (object sender, MouseEventArgs e)
+    internal void Tab_Selecting (object? sender, CommandEventArgs e)
     {
-        e.Handled = _tabsBar.NewMouseEvent (e) == true;
+        if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            e.Handled = _tabsBar.NewMouseEvent (mouseArgs) == true;
+        }
     }
 
     private void UnSetCurrentTabs ()
@@ -652,8 +655,8 @@ public class TabView : View
 
                 if (tab.Visible)
                 {
-                    tab.MouseClick -= Tab_MouseClick!;
-                    tab.Border!.MouseClick -= Tab_MouseClick!;
+                    tab.Selecting -= Tab_Selecting!;
+                    tab.Border!.Selecting -= Tab_Selecting!;
                     tab.Visible = false;
                 }
             }
@@ -662,8 +665,8 @@ public class TabView : View
         {
             foreach (Tab tabToRender in _tabLocations)
             {
-                tabToRender.MouseClick -= Tab_MouseClick!;
-                tabToRender.Border!.MouseClick -= Tab_MouseClick!;
+                tabToRender.Selecting -= Tab_Selecting!;
+                tabToRender.Border!.Selecting -= Tab_Selecting!;
                 tabToRender.Visible = false;
             }
 

+ 12 - 4
Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs

@@ -30,7 +30,7 @@ public abstract class CheckBoxTableSourceWrapperBase : ITableSource
 
         tableView.KeyBindings.ReplaceCommands (Key.Space, Command.Select);
 
-        tableView.MouseClick += TableView_MouseClick;
+        tableView.Selecting += TableView_Selecting;
         tableView.CellToggled += TableView_CellToggled;
     }
 
@@ -152,15 +152,22 @@ public abstract class CheckBoxTableSourceWrapperBase : ITableSource
         tableView.SetNeedsDraw ();
     }
 
-    private void TableView_MouseClick (object sender, MouseEventArgs e)
+#nullable enable
+    private void TableView_Selecting (object? sender, CommandEventArgs e)
     {
+        // Only handle mouse clicks, not keyboard selections
+        if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            return;
+        }
+
         // we only care about clicks (not movements)
-        if (!e.Flags.HasFlag (MouseFlags.Button1Clicked))
+        if (!mouseArgs.Flags.HasFlag (MouseFlags.Button1Clicked))
         {
             return;
         }
 
-        Point? hit = tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? headerIfAny);
+        Point? hit = tableView.ScreenToCell (mouseArgs.Position.X, mouseArgs.Position.Y, out int? headerIfAny);
 
         if (headerIfAny.HasValue && headerIfAny.Value == 0)
         {
@@ -191,4 +198,5 @@ public abstract class CheckBoxTableSourceWrapperBase : ITableSource
             tableView.SetNeedsDraw ();
         }
     }
+#nullable restore
 }

+ 12 - 4
Terminal.Gui/Views/TableView/TreeTableSource.cs

@@ -42,7 +42,7 @@ public class TreeTableSource<T> : IEnumerableTableSource<T>, IDisposable where T
         _tableView = table;
         _tree = tree;
         _tableView.KeyDown += Table_KeyPress;
-        _tableView.MouseClick += Table_MouseClick;
+        _tableView.Selecting += Table_Selecting;
 
         List<string> colList = subsequentColumns.Keys.ToList ();
         colList.Insert (0, firstColumnName);
@@ -56,7 +56,7 @@ public class TreeTableSource<T> : IEnumerableTableSource<T>, IDisposable where T
     public void Dispose ()
     {
         _tableView.KeyDown -= Table_KeyPress;
-        _tableView.MouseClick -= Table_MouseClick;
+        _tableView.Selecting -= Table_Selecting;
         _tree.Dispose ();
     }
 
@@ -168,9 +168,16 @@ public class TreeTableSource<T> : IEnumerableTableSource<T>, IDisposable where T
         }
     }
 
-    private void Table_MouseClick (object sender, MouseEventArgs e)
+#nullable enable
+    private void Table_Selecting (object? sender, CommandEventArgs e)
     {
-        Point? hit = _tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? headerIfAny, out int? offsetX);
+        // Only handle mouse clicks, not keyboard selections
+        if (e.Context is not CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            return;
+        }
+
+        Point? hit = _tableView.ScreenToCell (mouseArgs.Position.X, mouseArgs.Position.Y, out int? headerIfAny, out int? offsetX);
 
         if (hit is null || headerIfAny is { } || !IsInTreeColumn (hit.Value.X, false) || offsetX is null)
         {
@@ -202,4 +209,5 @@ public class TreeTableSource<T> : IEnumerableTableSource<T>, IDisposable where T
             _tableView.SetNeedsDraw ();
         }
     }
+#nullable restore
 }

+ 2 - 2
Tests/IntegrationTests/FluentTests/GuiTestContextMouseEventTests.cs

@@ -213,7 +213,7 @@ public class GuiTestContextMouseEventTests (ITestOutputHelper outputHelper)
             Height = 5
         };
 
-        view.MouseClick += (s, e) => clickCount++;
+        view.MouseEvent += (s, e) => clickCount++;
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view);
@@ -240,7 +240,7 @@ public class GuiTestContextMouseEventTests (ITestOutputHelper outputHelper)
             Height = 5
         };
 
-        view.MouseClick += (s, e) => clickCount++;
+        view.MouseEvent += (s, e) => clickCount++;
 
         using GuiTestContext context = With.A<Window> (40, 10, d, _out)
                                            .Add (view)

+ 1 - 1
Tests/UnitTests/Application/Mouse/ApplicationMouseTests.cs

@@ -119,7 +119,7 @@ public class ApplicationMouseTests
 
         var mouseEvent = new MouseEventArgs { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked };
 
-        view.MouseClick += (s, e) =>
+        view.MouseEvent += (s, e) =>
                            {
                                Assert.Equal (expectedX, e.Position.X);
                                Assert.Equal (expectedY, e.Position.Y);

+ 26 - 56
Tests/UnitTests/View/Mouse/MouseTests.cs

@@ -25,7 +25,7 @@ public class MouseTests : TestsAllViews
     [AutoInitShutdown]
     public void ButtonPressed_In_Border_Starts_Drag (int marginThickness, int borderThickness, int paddingThickness, int xy, bool expectedMoved)
     {
-        var testView = new View
+        View testView = new ()
         {
             CanFocus = true,
             X = 4,
@@ -38,7 +38,7 @@ public class MouseTests : TestsAllViews
         testView.Border!.Thickness = new (borderThickness);
         testView.Padding!.Thickness = new (paddingThickness);
 
-        var top = new Runnable ();
+        Runnable top = new ();
         top.Add (testView);
 
         SessionToken rs = Application.Begin (top);
@@ -61,9 +61,9 @@ public class MouseTests : TestsAllViews
     [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)]
     public void WantContinuousButtonPressed_False_Button_Press_Release_DoesNotClick (MouseFlags pressed, MouseFlags released, MouseFlags clicked)
     {
-        var me = new MouseEventArgs ();
+        MouseEventArgs me = new ();
 
-        var view = new View
+        View view = new ()
         {
             Width = 1,
             Height = 1,
@@ -72,7 +72,7 @@ public class MouseTests : TestsAllViews
 
         var clickedCount = 0;
 
-        view.MouseClick += (s, e) => clickedCount++;
+        view.MouseEvent += (s, e) => clickedCount += e.IsSingleDoubleOrTripleClicked ? 1 : 0;
 
         me.Flags = pressed;
         view.NewMouseEvent (me);
@@ -99,36 +99,6 @@ public class MouseTests : TestsAllViews
         Application.ResetState (true);
     }
 
-    [Theory]
-    [InlineData (MouseFlags.Button1Clicked)]
-    [InlineData (MouseFlags.Button2Clicked)]
-    [InlineData (MouseFlags.Button3Clicked)]
-    [InlineData (MouseFlags.Button4Clicked)]
-    public void WantContinuousButtonPressed_True_Button_Clicked_Raises_MouseClick (MouseFlags clicked)
-    {
-        var me = new MouseEventArgs ();
-
-        var view = new View
-        {
-            Width = 1,
-            Height = 1,
-            WantContinuousButtonPressed = true
-        };
-
-        var clickedCount = 0;
-
-        view.MouseClick += (s, e) => clickedCount++;
-
-        me.Flags = clicked;
-        view.NewMouseEvent (me);
-        Assert.Equal (1, clickedCount);
-
-        view.Dispose ();
-
-        // Button1Pressed, Button1Released cause Application.Mouse.MouseGrabView to be set
-        Application.ResetState (true);
-    }
-
     [Theory]
     [InlineData (MouseFlags.Button1Clicked)]
     [InlineData (MouseFlags.Button2Clicked)]
@@ -136,9 +106,9 @@ public class MouseTests : TestsAllViews
     [InlineData (MouseFlags.Button4Clicked)]
     public void WantContinuousButtonPressed_True_Button_Clicked_Raises_Selecting (MouseFlags clicked)
     {
-        var me = new MouseEventArgs ();
+        MouseEventArgs me = new ();
 
-        var view = new View
+        View view = new ()
         {
             Width = 1,
             Height = 1,
@@ -166,9 +136,9 @@ public class MouseTests : TestsAllViews
     [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)]
     public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Button_Press_Release_Clicks (MouseFlags pressed, MouseFlags released)
     {
-        var me = new MouseEventArgs ();
+        MouseEventArgs me = new ();
 
-        var view = new View
+        View view = new ()
         {
             Width = 1,
             Height = 1,
@@ -177,8 +147,8 @@ public class MouseTests : TestsAllViews
         };
 
         // Setup components for mouse held down
-        var timed = new TimedEvents ();
-        var grab = new MouseGrabHandler ();
+        TimedEvents timed = new ();
+        MouseGrabHandler grab = new ();
         view.MouseHeldDown = new MouseHeldDown (view, timed, grab);
 
         // Register callback for what to do when the mouse is held down
@@ -226,9 +196,9 @@ public class MouseTests : TestsAllViews
         MouseFlags clicked
     )
     {
-        var me = new MouseEventArgs ();
+        MouseEventArgs me = new ();
 
-        var view = new View
+        View view = new ()
         {
             Width = 1,
             Height = 1,
@@ -237,8 +207,8 @@ public class MouseTests : TestsAllViews
         };
 
         // Setup components for mouse held down
-        var timed = new TimedEvents ();
-        var grab = new MouseGrabHandler ();
+        TimedEvents timed = new ();
+        MouseGrabHandler grab = new ();
         view.MouseHeldDown = new MouseHeldDown (view, timed, grab);
 
         // Register callback for what to do when the mouse is held down
@@ -279,9 +249,9 @@ public class MouseTests : TestsAllViews
     [Fact]
     public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Move_InViewport_OutOfViewport_Keeps_Counting ()
     {
-        var me = new MouseEventArgs ();
+        MouseEventArgs me = new ();
 
-        var view = new View
+        View view = new ()
         {
             Width = 1,
             Height = 1,
@@ -290,8 +260,8 @@ public class MouseTests : TestsAllViews
         };
 
         // Setup components for mouse held down
-        var timed = new TimedEvents ();
-        var grab = new MouseGrabHandler ();
+        TimedEvents timed = new ();
+        MouseGrabHandler grab = new ();
         view.MouseHeldDown = new MouseHeldDown (view, timed, grab);
 
         // Register callback for what to do when the mouse is held down
@@ -352,7 +322,7 @@ public class MouseTests : TestsAllViews
     //[InlineData (true, MouseState.PressedOutside, 0, 0, 0, 1)]
     //public void MouseState_Button1_Pressed_Then_Released_Outside (bool inViewport, MouseState highlightFlags, int noneCount, int expectedInCount, int expectedPressedCount, int expectedPressedOutsideCount)
     //{
-    //    var testView = new MouseEventTestView
+    //    MouseEventTestView testView = new ()
     //    {
     //        HighlightStates = highlightFlags
     //    };
@@ -389,7 +359,7 @@ public class MouseTests : TestsAllViews
     [InlineData (10)]
     public void MouseState_None_Button1_Pressed_Move_No_Changes (int x)
     {
-        var testView = new MouseEventTestView
+        MouseEventTestView testView = new ()
         {
             HighlightStates = MouseState.None
         };
@@ -403,7 +373,7 @@ public class MouseTests : TestsAllViews
         Assert.Equal (0, testView.MouseStatePressedOutsideCount);
         Assert.Equal (0, testView.MouseStateNoneCount);
 
-        // Move to x,0 
+        // Move to x,0
         testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed, Position = new (x, 0) });
 
         if (inViewport)
@@ -421,7 +391,7 @@ public class MouseTests : TestsAllViews
             Assert.Equal (0, testView.MouseStateNoneCount);
         }
 
-        // Move backto 0,0 ; in viewport
+        // Move back to 0,0 ; in viewport
         testView.NewMouseEvent (new () { Flags = MouseFlags.Button1Pressed });
 
         if (inViewport)
@@ -451,7 +421,7 @@ public class MouseTests : TestsAllViews
     [InlineData (10)]
     public void MouseState_Pressed_Button1_Pressed_Move_Keeps_Pressed (int x)
     {
-        var testView = new MouseEventTestView
+        MouseEventTestView testView = new ()
         {
             HighlightStates = MouseState.Pressed
         };
@@ -513,7 +483,7 @@ public class MouseTests : TestsAllViews
     [InlineData (10)]
     public void MouseState_PressedOutside_Button1_Pressed_Move_Raises_PressedOutside (int x)
     {
-        var testView = new MouseEventTestView
+        MouseEventTestView testView = new ()
         {
             HighlightStates = MouseState.PressedOutside,
             WantContinuousButtonPressed = false
@@ -576,7 +546,7 @@ public class MouseTests : TestsAllViews
     [InlineData (10)]
     public void MouseState_PressedOutside_Button1_Pressed_Move_Raises_PressedOutside_WantContinuousButtonPressed (int x)
     {
-        var testView = new MouseEventTestView
+        MouseEventTestView testView = new ()
         {
             HighlightStates = MouseState.PressedOutside,
             WantContinuousButtonPressed = true

+ 3 - 3
Tests/UnitTests/Views/ShortcutTests.cs

@@ -55,9 +55,9 @@ public class ShortcutTests
     //  0123456789
     // " C  0  A "
     [InlineData (-1, 0, 0, 0, 0)]
-    [InlineData (0, 0, 1, 1, 1)] // mouseX = 0 is on the CommandView.Margin, so Shortcut will get MouseClick
-    [InlineData (1, 0, 1, 1, 1)] // mouseX = 1 is on the CommandView, so CommandView will get MouseClick
-    [InlineData (2, 0, 1, 1, 1)] // mouseX = 2 is on the CommandView.Margin, so Shortcut will get MouseClick
+    [InlineData (0, 0, 1, 1, 1)] // mouseX = 0 is on the CommandView.Margin, so Shortcut will get MouseEvent for click
+    [InlineData (1, 0, 1, 1, 1)] // mouseX = 1 is on the CommandView, so CommandView will get MouseEvent for click
+    [InlineData (2, 0, 1, 1, 1)] // mouseX = 2 is on the CommandView.Margin, so Shortcut will get MouseEvent for click
     [InlineData (3, 0, 1, 1, 1)]
     [InlineData (4, 0, 1, 1, 1)]
     [InlineData (5, 0, 1, 1, 1)]

+ 1 - 1
Tests/UnitTests/Views/TextFieldTests.cs

@@ -917,7 +917,7 @@ public class TextFieldTests (ITestOutputHelper output)
 
         var tf = new TextField { Width = 10 };
         var clickCounter = 0;
-        tf.MouseClick += (s, m) => { clickCounter++; };
+        tf.MouseEvent += (s, m) => { clickCounter++; };
 
         var top = new Runnable ();
         top.Add (tf);

+ 34 - 34
Tests/UnitTestsParallelizable/Application/MouseTests.cs

@@ -128,46 +128,46 @@ public class MouseTests
     [Theory]
 
     // click on border
-    [InlineData (0, 0, 0, 0, 0, false)]
-    [InlineData (0, 1, 0, 0, 0, false)]
-    [InlineData (0, 0, 1, 0, 0, false)]
-    [InlineData (0, 9, 0, 0, 0, false)]
-    [InlineData (0, 0, 9, 0, 0, false)]
+    [InlineData (0, 0, 0, 0, 0, 0)]
+    [InlineData (0, 1, 0, 0, 0, 0)]
+    [InlineData (0, 0, 1, 0, 0, 0)]
+    [InlineData (0, 9, 0, 0, 0, 0)]
+    [InlineData (0, 0, 9, 0, 0, 0)]
 
     // outside border
-    [InlineData (0, 10, 0, 0, 0, false)]
-    [InlineData (0, 0, 10, 0, 0, false)]
+    [InlineData (0, 10, 0, 0, 0, 0)]
+    [InlineData (0, 0, 10, 0, 0, 0)]
 
     // view is offset from origin ; click is on border
-    [InlineData (1, 1, 1, 0, 0, false)]
-    [InlineData (1, 2, 1, 0, 0, false)]
-    [InlineData (1, 1, 2, 0, 0, false)]
-    [InlineData (1, 10, 1, 0, 0, false)]
-    [InlineData (1, 1, 10, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 0)]
+    [InlineData (1, 2, 1, 0, 0, 0)]
+    [InlineData (1, 1, 2, 0, 0, 0)]
+    [InlineData (1, 10, 1, 0, 0, 0)]
+    [InlineData (1, 1, 10, 0, 0, 0)]
 
     // outside border
-    [InlineData (1, -1, 0, 0, 0, false)]
-    [InlineData (1, 0, -1, 0, 0, false)]
-    [InlineData (1, 10, 10, 0, 0, false)]
-    [InlineData (1, 11, 11, 0, 0, false)]
+    [InlineData (1, -1, 0, 0, 0, 0)]
+    [InlineData (1, 0, -1, 0, 0, 0)]
+    [InlineData (1, 10, 10, 0, 0, 0)]
+    [InlineData (1, 11, 11, 0, 0, 0)]
 
     // view is at origin, click is inside border
-    [InlineData (0, 1, 1, 0, 0, true)]
-    [InlineData (0, 2, 1, 1, 0, true)]
-    [InlineData (0, 1, 2, 0, 1, true)]
-    [InlineData (0, 8, 1, 7, 0, true)]
-    [InlineData (0, 1, 8, 0, 7, true)]
-    [InlineData (0, 8, 8, 7, 7, true)]
+    [InlineData (0, 1, 1, 0, 0, 1)]
+    [InlineData (0, 2, 1, 1, 0, 1)]
+    [InlineData (0, 1, 2, 0, 1, 1)]
+    [InlineData (0, 8, 1, 7, 0, 1)]
+    [InlineData (0, 1, 8, 0, 7, 1)]
+    [InlineData (0, 8, 8, 7, 7, 1)]
 
     // view is offset from origin ; click inside border
     // our view is 10x10, but has a border, so it's bounds is 8x8
-    [InlineData (1, 2, 2, 0, 0, true)]
-    [InlineData (1, 3, 2, 1, 0, true)]
-    [InlineData (1, 2, 3, 0, 1, true)]
-    [InlineData (1, 9, 2, 7, 0, true)]
-    [InlineData (1, 2, 9, 0, 7, true)]
-    [InlineData (1, 9, 9, 7, 7, true)]
-    [InlineData (1, 10, 10, 7, 7, false)]
+    [InlineData (1, 2, 2, 0, 0, 1)]
+    [InlineData (1, 3, 2, 1, 0, 1)]
+    [InlineData (1, 2, 3, 0, 1, 1)]
+    [InlineData (1, 9, 2, 7, 0, 1)]
+    [InlineData (1, 2, 9, 0, 7, 1)]
+    [InlineData (1, 9, 9, 7, 7, 1)]
+    [InlineData (1, 10, 10, 7, 7, 0)]
 
     //01234567890123456789
     // |12345678|
@@ -178,13 +178,13 @@ public class MouseTests
         int clickY,
         int expectedX,
         int expectedY,
-        bool expectedClicked
+        int expectedClickedCount
     )
     {
         Size size = new (10, 10);
         Point pos = new (offset, offset);
 
-        var clicked = false;
+        int clickedCount = 0;
 
         using IApplication? application = Application.Create ();
 
@@ -208,14 +208,14 @@ public class MouseTests
 
         var mouseEvent = new MouseEventArgs { Position = new (clickX, clickY), ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked };
 
-        view.MouseClick += (s, e) =>
+        view.MouseEvent += (_s, e) =>
         {
             Assert.Equal (expectedX, e.Position.X);
             Assert.Equal (expectedY, e.Position.Y);
-            clicked = true;
+            clickedCount += e.IsSingleDoubleOrTripleClicked ? 1 : 0;
         };
 
         application.Mouse.RaiseMouseEvent (mouseEvent);
-        Assert.Equal (expectedClicked, clicked);
+        Assert.Equal (expectedClickedCount, clickedCount);
     }
 }

+ 38 - 46
Tests/UnitTestsParallelizable/ViewBase/Mouse/MouseEventRoutingTests.cs

@@ -32,9 +32,9 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
         };
 
         Point? receivedPosition = null;
-        var eventReceived = false;
+        bool eventReceived = false;
 
-        view.MouseEvent += (sender, args) =>
+        view.MouseEvent += (_, args) =>
         {
             eventReceived = true;
             receivedPosition = args.Position;
@@ -90,9 +90,9 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
         };
 
         Point? receivedPosition = null;
-        var eventReceived = false;
+        bool eventReceived = false;
 
-        view.MouseEvent += (sender, args) =>
+        view.MouseEvent += (_, args) =>
         {
             eventReceived = true;
             receivedPosition = args.Position;
@@ -100,7 +100,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (viewRelativeX, viewRelativeY),
+            Position = new (viewRelativeX, viewRelativeY),
             Flags = MouseFlags.Button1Clicked
         };
 
@@ -146,9 +146,9 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
         superView.Add (subView);
 
         Point? subViewReceivedPosition = null;
-        var subViewEventReceived = false;
+        bool subViewEventReceived = false;
 
-        subView.MouseEvent += (sender, args) =>
+        subView.MouseEvent += (_, args) =>
         {
             subViewEventReceived = true;
             subViewReceivedPosition = args.Position;
@@ -175,7 +175,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
     }
 
     [Fact]
-    public void MouseClick_OnSubView_RaisesMouseClickEvent ()
+    public void MouseClick_OnSubView_RaisesSelectingEvent ()
     {
         // Arrange
         View superView = new ()
@@ -194,8 +194,8 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
 
         superView.Add (subView);
 
-        var clickCount = 0;
-        subView.MouseClick += (sender, args) => clickCount++;
+        int selectingCount = 0;
+        subView.Selecting += (_, _) => selectingCount++;
 
         MouseEventArgs mouseEvent = new ()
         {
@@ -207,7 +207,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
         subView.NewMouseEvent (mouseEvent);
 
         // Assert
-        Assert.Equal (1, clickCount);
+        Assert.Equal (1, selectingCount);
 
         subView.Dispose ();
         superView.Dispose ();
@@ -222,20 +222,20 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
     {
         // Arrange
         View view = new () { Width = 10, Height = 10 };
-        var handlerCalled = false;
-        var clickHandlerCalled = false;
+        bool handlerCalled = false;
+        bool clickHandlerCalled = false;
 
-        view.MouseEvent += (sender, args) =>
+        view.MouseEvent += (_, args) =>
         {
             handlerCalled = true;
             args.Handled = true; // Mark as handled
         };
 
-        view.MouseClick += (sender, args) => { clickHandlerCalled = true; };
+        view.MouseEvent += (_, e) => { clickHandlerCalled = !e.IsSingleDoubleOrTripleClicked; ; };
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = MouseFlags.Button1Clicked
         };
 
@@ -255,20 +255,17 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
     {
         // Arrange
         View view = new () { Width = 10, Height = 10 };
-        var eventHandlerCalled = false;
-        var clickHandlerCalled = false;
+        bool eventHandlerCalled = false;
 
-        view.MouseEvent += (sender, args) =>
+        view.MouseEvent += (_, _) =>
         {
             eventHandlerCalled = true;
             // Don't set Handled = true
         };
 
-        view.MouseClick += (sender, args) => { clickHandlerCalled = true; };
-
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = MouseFlags.Button1Clicked
         };
 
@@ -277,7 +274,6 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
 
         // Assert
         Assert.True (eventHandlerCalled);
-        Assert.True (clickHandlerCalled); // Click handler should be called when event is not handled
 
         view.Dispose ();
     }
@@ -294,11 +290,10 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
     {
         // Arrange
         View view = new () { Width = 10, Height = 10 };
-        var pressedCount = 0;
-        var releasedCount = 0;
-        var clickedCount = 0;
+        int pressedCount = 0;
+        int releasedCount = 0;
 
-        view.MouseEvent += (sender, args) =>
+        view.MouseEvent += (_, args) =>
         {
             if (args.Flags.HasFlag (MouseFlags.Button1Pressed))
             {
@@ -311,11 +306,9 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
             }
         };
 
-        view.MouseClick += (sender, args) => { clickedCount++; };
-
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = flags
         };
 
@@ -325,7 +318,6 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
         // Assert
         Assert.Equal (expectedPressed, pressedCount);
         Assert.Equal (expectedReleased, releasedCount);
-        Assert.Equal (expectedClicked, clickedCount);
 
         view.Dispose ();
     }
@@ -339,13 +331,13 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
     {
         // Arrange
         View view = new () { Width = 10, Height = 10 };
-        var clickCount = 0;
+        int clickCount = 0;
 
-        view.MouseClick += (sender, args) => clickCount++;
+        view.MouseEvent += (_, a) => clickCount += a.IsSingleDoubleOrTripleClicked ? 1 : 0;
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = clickFlag
         };
 
@@ -373,12 +365,12 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
             Enabled = false
         };
 
-        var eventCalled = false;
-        view.MouseEvent += (sender, args) => { eventCalled = true; };
+        bool eventCalled = false;
+        view.MouseEvent += (_, _) => { eventCalled = true; };
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = MouseFlags.Button1Clicked
         };
 
@@ -392,7 +384,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
     }
 
     [Fact]
-    public void View_Disabled_DoesNotRaiseMouseClickEvent ()
+    public void View_Disabled_DoesNotRaiseSelectingEvent ()
     {
         // Arrange
         View view = new ()
@@ -402,12 +394,12 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
             Enabled = false
         };
 
-        var clickCalled = false;
-        view.MouseClick += (sender, args) => { clickCalled = true; };
+        bool selectingCalled = false;
+        view.Selecting += (_, _) => { selectingCalled = true; };
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = MouseFlags.Button1Clicked
         };
 
@@ -415,7 +407,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
         view.NewMouseEvent (mouseEvent);
 
         // Assert
-        Assert.False (clickCalled);
+        Assert.False (selectingCalled);
 
         view.Dispose ();
     }
@@ -445,7 +437,7 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (2, 2),
+            Position = new (2, 2),
             Flags = MouseFlags.Button1Clicked
         };
 
@@ -475,12 +467,12 @@ public class MouseEventRoutingTests (ITestOutputHelper output)
 
         superView.Add (view);
 
-        var selectingCount = 0;
-        view.Selecting += (sender, args) => selectingCount++;
+        int selectingCount = 0;
+        view.Selecting += (_, _) => selectingCount++;
 
         MouseEventArgs mouseEvent = new ()
         {
-            Position = new Point (5, 5),
+            Position = new (5, 5),
             Flags = MouseFlags.Button1Clicked
         };
 

+ 1 - 2
docfx/docs/View.md

@@ -148,7 +148,7 @@ See the [Mouse Deep Dive](mouse.md).
 - [View.WantContinuousButtonPresses](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_WantContinuousButtonPresses) - Enables continuous button press events
 - [View.Highlight](~/api/Terminal.Gui.ViewBase.View.yml) - Event for visual feedback on mouse hover/click
 - [View.HighlightStyle](~/api/Terminal.Gui.ViewBase.View.yml#Terminal_Gui_ViewBase_View_HighlightStyle) - Visual style when highlighted
-- Events: `MouseEnter`, `MouseLeave`, `MouseClick`, `MouseEvent`
+- Events: `MouseEnter`, `MouseLeave`, `MouseEvent`
 
 ### Layout and Arrangement
 
@@ -368,7 +368,6 @@ The mouse subsystem processes mouse events through:
 3. [View.MouseEnter](~/api/Terminal.Gui.ViewBase.View.yml) / [View.MouseLeave](~/api/Terminal.Gui.ViewBase.View.yml) events
 4. [View.MouseBindings](~/api/Terminal.Gui.ViewBase.View.yml) - Converts mouse actions to commands
 5. Command handlers
-6. [View.MouseClick](~/api/Terminal.Gui.ViewBase.View.yml) event (high-level)
 
 ### Layout
 

+ 110 - 6
docfx/docs/migratingfromv1.md

@@ -555,7 +555,7 @@ void HandleMouse(object? sender, MouseEventArgs args) { }
 
 ```csharp
 // v2 - Viewport-relative coordinates
-view.MouseClick += (s, e) =>
+view.MouseEvent += (s, e) =>
 {
     // e.Position is relative to view's Viewport
     var x = e.Position.X; // 0 = left edge of viewport
@@ -563,16 +563,120 @@ view.MouseClick += (s, e) =>
 };
 ```
 
-### Highlight Event
+### Mouse Click Handling
 
-v2 adds a `Highlight` event for visual feedback:
+**v1:**
+```csharp
+// v1 - MouseClick event
+view.MouseClick += (mouseEvent) =>
+{
+    // Handle click
+    DoSomething();
+};
+```
+
+**v2:**
+```csharp
+// v2 - Use MouseBindings + Commands + Selecting event
+view.MouseBindings.Add(MouseFlags.Button1Clicked, Command.Select);
+view.Selecting += (s, e) =>
+{
+    // Handle selection (called when Button1Clicked)
+    DoSomething();
+};
+
+// Alternative: Use MouseEvent for low-level handling
+view.MouseEvent += (s, e) =>
+{
+    if (e.Flags.HasFlag(MouseFlags.Button1Clicked))
+    {
+        DoSomething();
+        e.Handled = true;
+    }
+};
+```
+
+**Key Changes:**
+- `View.MouseClick` event has been **removed**
+- Use `MouseBindings` to map mouse events to `Command`s
+- Default mouse bindings invoke `Command.Select` which raises the `Selecting` event
+- For custom behavior, override `OnSelecting` or subscribe to the `Selecting` event
+- For low-level mouse handling, use `MouseEvent` directly
+
+**Migration Pattern:**
+```csharp
+// ❌ v1 - OnMouseClick override
+protected override bool OnMouseClick(MouseEventArgs mouseEvent)
+{
+    if (mouseEvent.Flags.HasFlag(MouseFlags.Button1Clicked))
+    {
+        PerformAction();
+        return true;
+    }
+    return base.OnMouseClick(mouseEvent);
+}
+
+// ✅ v2 - OnSelecting override
+protected override bool OnSelecting(CommandEventArgs args)
+{
+    if (args.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+    {
+        // Access mouse position and flags via context
+        if (mouseArgs.Flags.HasFlag(MouseFlags.Button1Clicked))
+        {
+            PerformAction();
+            return true;
+        }
+    }
+    return base.OnSelecting(args);
+}
+
+// ✅ v2 - Selecting event (simpler)
+view.Selecting += (s, e) =>
+{
+    PerformAction();
+    e.Handled = true;
+};
+```
+
+**Accessing Mouse Position in Selecting Event:**
+```csharp
+view.Selecting += (s, e) =>
+{
+    // Extract mouse event args from command context
+    if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+    {
+        Point position = mouseArgs.Position;
+        MouseFlags flags = mouseArgs.Flags;
+        
+        // Use position and flags for custom logic
+        HandleClick(position, flags);
+        e.Handled = true;
+    }
+};
+```
+
+### Mouse State and Highlighting
+
+v2 adds enhanced mouse state tracking:
 
 ```csharp
-view.Highlight += (s, e) =>
+// Configure which mouse states trigger highlighting
+view.HighlightStates = MouseState.In | MouseState.Pressed;
+
+// React to mouse state changes
+view.MouseStateChanged += (s, e) =>
 {
-    // Provide visual feedback on mouse hover
+    switch (e.Value)
+    {
+        case MouseState.In:
+            // Mouse entered view
+            break;
+        case MouseState.Pressed:
+            // Mouse button pressed in view
+            break;
+    }
 };
-view.HighlightStyle = HighlightStyle.Hover;
 ```
 
 See [Mouse Deep Dive](mouse.md) for complete details.

+ 154 - 22
docfx/docs/mouse.md

@@ -44,8 +44,12 @@ public class MyView : View
         AddCommand (Command.ScrollDown, () => ScrollVertical (1));
         MouseBindings.Add (MouseFlags.WheelDown, Command.ScrollDown);
         
-        AddCommand (Command.Select, () => SelectItem());
-        MouseBindings.Add (MouseFlags.Button1Clicked, Command.Select);
+        // Mouse clicks invoke Command.Select by default
+        // Override to customize click behavior
+        AddCommand (Command.Select, () => {
+            SelectItem();
+            return true;
+        });
     }
 }
 ```
@@ -56,17 +60,65 @@ The @Terminal.Gui.Input.Command enum lists generic operations that are implement
 
 Here are some common mouse binding patterns used throughout Terminal.Gui:
 
-* **Click Events**: `MouseFlags.Button1Clicked` for primary selection/activation
+* **Click Events**: `MouseFlags.Button1Clicked` for primary selection/activation - maps to `Command.Select` by default
 * **Double-Click Events**: `MouseFlags.Button1DoubleClicked` for default actions (like opening/accepting)
 * **Right-Click Events**: `MouseFlags.Button3Clicked` for context menus
 * **Scroll Events**: `MouseFlags.WheelUp` and `MouseFlags.WheelDown` for scrolling content
 * **Drag Events**: `MouseFlags.Button1Pressed` combined with mouse move tracking for drag operations
 
+### Default Mouse Bindings
+
+By default, all views have the following mouse bindings configured:
+
+```cs
+MouseBindings.Add (MouseFlags.Button1Clicked, Command.Select);
+MouseBindings.Add (MouseFlags.Button2Clicked, Command.Select);
+MouseBindings.Add (MouseFlags.Button3Clicked, Command.Select);
+MouseBindings.Add (MouseFlags.Button4Clicked, Command.Select);
+MouseBindings.Add (MouseFlags.Button1Clicked | MouseFlags.ButtonCtrl, Command.Select);
+```
+
+When a mouse click occurs, the `Command.Select` is invoked, which raises the `Selecting` event. Views can override `OnSelecting` or subscribe to the `Selecting` event to handle clicks:
+
+```cs
+public class MyView : View
+{
+    public MyView()
+    {
+        // Option 1: Subscribe to Selecting event
+        Selecting += (s, e) =>
+        {
+            if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+            {
+                // Access mouse position and flags
+                HandleSelection(mouseArgs.Position, mouseArgs.Flags);
+                e.Handled = true;
+            }
+        };
+    }
+    
+    // Option 2: Override OnSelecting
+    protected override bool OnSelecting(CommandEventArgs args)
+    {
+        if (args.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            // Custom selection logic with mouse position
+            if (mouseArgs.Position.Y == 0)
+            {
+                HandleHeaderClick();
+                return true;
+            }
+        }
+        return base.OnSelecting(args);
+    }
+}
+```
+
 ## Mouse Events
 
 At the core of *Terminal.Gui*'s mouse API is the @Terminal.Gui.Input.MouseEventArgs class. The @Terminal.Gui.Input.MouseEventArgs class provides a platform-independent abstraction for common mouse events. Every mouse event can be fully described in a @Terminal.Gui.Input.MouseEventArgs instance, and most of the mouse-related APIs are simply helper functions for decoding a @Terminal.Gui.Input.MouseEventArgs.
 
-When the user does something with the mouse, the driver maps the platform-specific mouse event into a `MouseEventArgs` and calls `IApplication.Mouse.RaiseMouseEvent`. Then, `IApplication.Mouse.RaiseMouseEvent` determines which `View` the event should go to. The `View.OnMouseEvent` method can be overridden or the `View.MouseEvent` event can be subscribed to, to handle the low-level mouse event. If the low-level event is not handled by a view, `IApplication` will then call the appropriate high-level helper APIs. For example, if the user double-clicks the mouse, `View.OnMouseClick` will be called/`View.MouseClick` will be raised with the event arguments indicating which mouse button was double-clicked. 
+When the user does something with the mouse, the driver maps the platform-specific mouse event into a `MouseEventArgs` and calls `IApplication.Mouse.RaiseMouseEvent`. Then, `IApplication.Mouse.RaiseMouseEvent` determines which `View` the event should go to. The `View.OnMouseEvent` method can be overridden or the `View.MouseEvent` event can be subscribed to, to handle the low-level mouse event. If the low-level event is not handled by a view, `IApplication` will then call the appropriate high-level helper APIs.
 
 ### Mouse Event Processing Flow
 
@@ -77,8 +129,9 @@ Mouse events are processed through the following workflow using the [Cancellable
 3. **View Level**: The target view processes the event through:
    - `OnMouseEvent` (virtual method that can be overridden)
    - `MouseEvent` event (for event subscribers)
-   - Mouse bindings (if the event wasn't handled)
-   - High-level events like `OnMouseClick`, `MouseEnter`, `MouseLeave`
+   - Mouse bindings (if the event wasn't handled) which invoke commands
+   - Command handlers (e.g., `OnSelecting` for `Command.Select`)
+   - High-level events like `MouseEnter`, `MouseLeave`
 
 ### Handling Mouse Events Directly
 
@@ -114,15 +167,76 @@ public class CustomView : View
 }
 ```
 
+### Handling Mouse Clicks
+
+The recommended pattern for handling mouse clicks is to use the `Selecting` event or override `OnSelecting`. This integrates with the command system and provides access to mouse event details through the command context:
+
+```cs
+public class ClickableView : View
+{
+    public ClickableView()
+    {
+        Selecting += OnSelecting;
+    }
+    
+    private void OnSelecting(object sender, CommandEventArgs e)
+    {
+        // Extract mouse event information from command context
+        if (e.Context is CommandContext<MouseBinding> { Binding.MouseEventArgs: { } mouseArgs })
+        {
+            // Access mouse position (viewport-relative)
+            Point clickPosition = mouseArgs.Position;
+            
+            // Check which button was clicked
+            if (mouseArgs.Flags.HasFlag(MouseFlags.Button1Clicked))
+            {
+                HandleLeftClick(clickPosition);
+            }
+            else if (mouseArgs.Flags.HasFlag(MouseFlags.Button3Clicked))
+            {
+                ShowContextMenu(clickPosition);
+            }
+            
+            e.Handled = true;
+        }
+    }
+}
+```
+
+For views that need different behavior for different mouse buttons, configure custom mouse bindings:
+
+```cs
+public class MultiButtonView : View
+{
+    public MultiButtonView()
+    {
+        // Clear default bindings
+        MouseBindings.Clear();
+        
+        // Map different buttons to different commands
+        MouseBindings.Add(MouseFlags.Button1Clicked, Command.Select);
+        MouseBindings.Add(MouseFlags.Button3Clicked, Command.ContextMenu);
+        
+        AddCommand(Command.ContextMenu, HandleContextMenu);
+    }
+    
+    private bool HandleContextMenu()
+    {
+        // Show context menu
+        return true;
+    }
+}
+```
+
 ## Mouse State
 
 The @Terminal.Gui.ViewBase.View.MouseState property provides an abstraction for the current state of the mouse, enabling views to do interesting things like change their appearance based on the mouse state.
 
 Mouse states include:
 * **Normal** - Default state when mouse is not interacting with the view
-* **Over** - Mouse is positioned over the view
+* **In** - Mouse is positioned over the view (inside the viewport)
 * **Pressed** - Mouse button is pressed down while over the view
-* **Clicked** - Mouse was clicked on the view
+* **PressedOutside** - Mouse was pressed inside but moved outside the view
 
 It works in conjunction with the @Terminal.Gui.ViewBase.View.HighlightStates which is a list of mouse states that will cause a view to become highlighted.
 
@@ -131,9 +245,9 @@ Subscribe to the @Terminal.Gui.ViewBase.View.MouseStateChanged event to be notif
 ```cs
 view.MouseStateChanged += (sender, e) => 
 {
-    switch (e.NewState)
+    switch (e.Value)
     {
-        case MouseState.Over:
+        case MouseState.In:
             // Change appearance when mouse hovers
             break;
         case MouseState.Pressed:
@@ -143,6 +257,13 @@ view.MouseStateChanged += (sender, e) =>
 };
 ```
 
+Configure which states should cause highlighting:
+
+```cs
+// Highlight when mouse is over the view or when pressed
+view.HighlightStates = MouseState.In | MouseState.Pressed;
+```
+
 ## Mouse Button and Movement Concepts
 
 * **Down** - Indicates the user pushed a mouse button down.
@@ -150,6 +271,7 @@ view.MouseStateChanged += (sender, e) =>
 * **Released** - Indicates the user released a mouse button.
 * **Clicked** - Indicates the user pressed then released the mouse button while over a particular View. 
 * **Double-Clicked** - Indicates the user clicked twice in rapid succession.
+* **Triple-Clicked** - Indicates the user clicked three times in rapid succession.
 * **Moved** - Indicates the mouse moved to a new location since the last mouse event.
 * **Wheel** - Indicates the mouse wheel was scrolled up or down.
 
@@ -179,7 +301,7 @@ public class MyView : View
         if (mouseEvent.Flags.HasFlag(MouseFlags.Button3Clicked))
         {
             // Access application mouse functionality through View.App
-            App?.MouseEvent?.Invoke(this, mouseEvent);
+            App?.Mouse?.RaiseMouseEvent(mouseEvent);
             return true;
         }
         return base.OnMouseEvent(mouseEvent);
@@ -209,16 +331,31 @@ view.MouseLeave += (sender, e) =>
 
 Mouse coordinates in Terminal.Gui are provided in multiple coordinate systems:
 
-* **Screen Coordinates** - Relative to the entire terminal screen (0,0 is top-left of terminal)
-* **View Coordinates** - Relative to the view's content area (0,0 is top-left of view's viewport)
+* **Screen Coordinates** - Relative to the entire terminal screen (0,0 is top-left of terminal) - available via `MouseEventArgs.ScreenPosition`
+* **View Coordinates** - Relative to the view's viewport (0,0 is top-left of view's viewport) - available via `MouseEventArgs.Position`
 
 The `MouseEventArgs` provides both coordinate systems:
-* `MouseEventArgs.Position` - Screen coordinates
-* `MouseEventArgs.ViewPosition` - View-relative coordinates (when available)
+* `MouseEventArgs.ScreenPosition` - Screen coordinates (absolute position on screen)
+* `MouseEventArgs.Position` - Viewport-relative coordinates (position within the view's content area)
+
+When handling mouse events in views, use `Position` for viewport-relative coordinates:
+
+```cs
+view.MouseEvent += (s, e) =>
+{
+    // e.Position is viewport-relative
+    if (e.Position.X < 10 && e.Position.Y < 5)
+    {
+        // Click in top-left corner of viewport
+    }
+};
+```
 
 ## Best Practices
 
-* **Use Mouse Bindings** when possible for simple mouse interactions - they integrate well with the Command system
+* **Use Mouse Bindings and Commands** for simple mouse interactions - they integrate well with the Command system and work alongside keyboard bindings
+* **Use the `Selecting` event** to handle mouse clicks - it's raised by the default `Command.Select` binding for all mouse buttons
+* **Access mouse details via CommandContext** when you need position or flags in `Selecting` handlers
 * **Handle Mouse Events directly** for complex interactions like drag-and-drop or custom gestures  
 * **Respect platform conventions** - use right-click for context menus, double-click for default actions
 * **Provide keyboard alternatives** - ensure all mouse functionality has keyboard equivalents
@@ -231,9 +368,4 @@ The `MouseEventArgs` provides both coordinate systems:
 * Mouse wheel support may vary between platforms and terminals
 * Some terminals may not support all mouse buttons or modifier keys
 * Mouse coordinates are limited to character cell boundaries - sub-character precision is not available
-* Performance can be impacted by excessive mouse move event handling - use mouse enter/leave events when appropriate rather than tracking all mouse moves
-
-
-
-
-
+* Performance can be impacted by excessive mouse move event handling - use mouse enter/leave events when appropriate rather than tracking all mouse moves

+ 1 - 1
docfx/docs/navigation.md

@@ -7,7 +7,7 @@ This document covers Terminal.Gui's navigation system, which determines:
 - What are the visual cues that help the user know what keystrokes will change the focus?
 - What are the visual cues that help the user know what keystrokes will cause action in elements of the application that don't currently have focus?
 - What is the order in which UI elements are traversed when using keyboard navigation?
-- What are the default actions for standard key/mouse input (e.g. Hotkey, `Space`, `Enter`, `MouseClick`)?
+- What are the default actions for standard key/mouse input (e.g. Hotkey, `Space`, `Enter`, or a mouse click)?
 
 ## See Also