Tig 9 月之前
父节点
当前提交
3649a047f2

+ 1 - 0
Terminal.Gui/Application/Application.Mouse.cs

@@ -147,6 +147,7 @@ public static partial class Application // Mouse handling
         }
 
         // The position of the mouse is the same as the screen position at the application level.
+        //Debug.Assert (mouseEvent.Position == mouseEvent.ScreenPosition);
         mouseEvent.Position = mouseEvent.ScreenPosition;
 
         List<View?> currentViewsUnderMouse = View.GetViewsUnderMouse (mouseEvent.ScreenPosition);

+ 2 - 2
Terminal.Gui/View/Adornment/Adornment.cs

@@ -223,8 +223,8 @@ public class Adornment : View
             return false;
         }
 
-        Rectangle outside = Parent.Frame;
-        //outside.Offset (Parent.Frame.Location);
+        Rectangle outside = Frame;
+        outside.Offset (Parent.Frame.Location);
 
         return Thickness.Contains (outside, location);
     }

+ 5 - 0
Terminal.Gui/View/View.Command.cs

@@ -108,6 +108,11 @@ public partial class View // Command APIs
         // If the event is not canceled by the virtual method, raise the event to notify any external subscribers.
         Select?.Invoke (this, args);
 
+        if ((Select is null || !args.Handled) && CanFocus)
+        {
+            SetFocus ();
+        }
+
         return Select is null ? null : args.Handled;
     }
 

+ 4 - 5
Terminal.Gui/View/View.Mouse.cs

@@ -369,11 +369,10 @@ public partial class View // Mouse APIs
         }
 
         // Post-conditions
-        if (!HasFocus && CanFocus)
-        {
-            args.Handled = true;
-            SetFocus ();
-        }
+
+        // Always invoke Select command on MouseClick
+        // By default, this will raise Select/OnSelect - Subclasses can override this via AddCommand (Command.Select ...).
+        args.Handled = InvokeCommand (Command.Select) == true;
 
         return args.Handled;
     }

+ 8 - 5
Terminal.Gui/Views/CheckBox.cs

@@ -148,11 +148,6 @@ public class CheckBox : View
 
         CheckedStateChanged?.Invoke (this, args);
 
-        if (RaiseSelectEvent () == true)
-        {
-            return true;
-        }
-
         return false;
     }
 
@@ -220,6 +215,14 @@ public class CheckBox : View
 
         bool? cancelled = ChangeCheckedState (e.NewValue);
 
+        if (cancelled is null or false)
+        {
+            if (RaiseSelectEvent () == true)
+            {
+                return true;
+            }
+        }
+
         return cancelled;
     }
 

+ 10 - 2
Terminal.Gui/Views/NumericUpDown.cs

@@ -133,9 +133,17 @@ public class NumericUpDown<T> : View where T : notnull
 
         return;
 
-        void OnDownButtonOnAccept (object? s, HandledEventArgs e) { InvokeCommand (Command.ScrollDown); }
+        void OnDownButtonOnAccept (object? s, HandledEventArgs e)
+        {
+            InvokeCommand (Command.ScrollDown);
+            e.Handled = true;
+        }
 
-        void OnUpButtonOnAccept (object? s, HandledEventArgs e) { InvokeCommand (Command.ScrollUp); }
+        void OnUpButtonOnAccept (object? s, HandledEventArgs e)
+        {
+            InvokeCommand (Command.ScrollUp);
+            e.Handled = true;
+        }
     }
 
     private T _value = default!;

+ 15 - 19
Terminal.Gui/Views/RadioGroup.cs

@@ -70,6 +70,8 @@ public class RadioGroup : View, IDesignable, IOrientation
                         return true;
                     }
                    );
+
+        // Select (Space key or mouse click) - The default implementation sets focus. RadioGroup does not.
         AddCommand (
                     Command.Select,
                     () =>
@@ -82,23 +84,17 @@ public class RadioGroup : View, IDesignable, IOrientation
                             }
                         }
 
-                        SelectedItem = Cursor;
+                        if (ChangeSelectedItem (Cursor) is true)
+                        {
+                            return true;
+                        };
 
-                        return true;
-                    });
-        AddCommand (
-                    Command.Select,
-                    () =>
-                    {
-                        if (SelectedItem == Cursor)
+                        if (RaiseSelectEvent () == true)
                         {
-                            if (!MoveDownRight ())
-                            {
-                                MoveHome ();
-                            }
+                            return true;
                         }
 
-                        return ChangeSelectedItem (Cursor) is false or null;
+                        return false;
                     });
 
         // Accept (Enter key) - Raise Accept event - DO NOT advance state
@@ -127,7 +123,12 @@ public class RadioGroup : View, IDesignable, IOrientation
                             }
 
                             // If a RadioItem.HotKey is pressed we always set the selected item - never SetFocus
-                            if (ChangeSelectedItem (item.Value) is null or false)
+                            if (ChangeSelectedItem (item.Value) == true)
+                            {
+                                return true;
+                            }
+
+                            if (RaiseSelectEvent () == true)
                             {
                                 return true;
                             }
@@ -331,11 +332,6 @@ public class RadioGroup : View, IDesignable, IOrientation
             return null;
         }
 
-        if (RaiseSelectEvent () == true)
-        {
-            return true;
-        }
-
         int savedSelected = _selected;
         _selected = value;
         Cursor = Math.Max (_selected, 0);

+ 35 - 28
Terminal.Gui/Views/Shortcut.cs

@@ -121,10 +121,16 @@ public class Shortcut : View, IOrientation, IDesignable
         KeyView.CanFocus = false;
         Add (KeyView);
 
-        // If the user clicks anywhere on the Shortcut, other than the CommandView, invoke the Command
+        // If the user clicks anywhere on the Shortcut...
         MouseClick += Shortcut_MouseClick;
-        //HelpView.MouseClick += Subview_MouseClick;
-        //KeyView.MouseClick += Subview_MouseClick;
+
+        // If the user clicks on HelpView or KeyView
+        HelpView.MouseClick += HelpOrKeyView_MouseClick;
+        KeyView.MouseClick += HelpOrKeyView_MouseClick;
+
+        HelpView.Select += HelpAndKeyViewOnSelect;
+        KeyView.Select += HelpAndKeyViewOnSelect;
+
         LayoutStarted += OnLayoutStarted;
         Initialized += OnInitialized;
 
@@ -170,6 +176,11 @@ public class Shortcut : View, IOrientation, IDesignable
         }
     }
 
+    private void HelpAndKeyViewOnSelect (object sender, HandledEventArgs e)
+    {
+        e.Handled = InvokeCommand (Command.Accept) == true;
+    }
+
     [CanBeNull]
     private readonly View _targetView; // If set, _command will be invoked
 
@@ -376,22 +387,20 @@ public class Shortcut : View, IOrientation, IDesignable
         if (!e.Handled)
         {
             // If the subview (likely CommandView) didn't handle the mouse click, invoke the Select command.
-            e.Handled = CommandView.InvokeCommand (Command.Accept) == true;
+            // e.Handled = CommandView.InvokeCommand (Command.Select) == true;
+            e.Handled = InvokeCommand (Command.Accept) == true;
         }
 
-        if (CanFocus)
-        {
-            SetFocus ();
-        }
+        //if (CanFocus)
+        //{
+        //    SetFocus ();
+        //}
     }
 
-    private void Subview_MouseClick (object sender, MouseEventEventArgs e)
+    private void HelpOrKeyView_MouseClick (object sender, MouseEventEventArgs e)
     {
-        if (!e.Handled)
-        {
-            // If the subview (likely CommandView) didn't handle the mouse click, invoke the command.
-            e.Handled = InvokeCommand (Command.Accept) == true;
-        }
+        // Always eat
+        //e.Handled = true;
     }
 
     #region IOrientation members
@@ -514,7 +523,7 @@ public class Shortcut : View, IOrientation, IDesignable
 
             Title = _commandView.Text;
 
-            _commandView.Accept += CommandViewOnAccept;
+            _commandView.Select += CommandViewOnAccept;
 
             void CommandViewOnAccept (object sender, HandledEventArgs e)
             {
@@ -522,8 +531,6 @@ public class Shortcut : View, IOrientation, IDesignable
                 e.Handled = true;
             }
 
-            _commandView.Select += CommandViewOnSelect;
-
             _commandView.MouseClick += CommandViewOnMouseClick;
 
             void CommandViewOnMouseClick (object sender, MouseEventEventArgs e)
@@ -532,17 +539,10 @@ public class Shortcut : View, IOrientation, IDesignable
                 {
                     // If the subview (likely CommandView) didn't handle the mouse click, invoke the command.
                     InvokeCommand (Command.HotKey);
+                    e.Handled = true;
                 }
             }
 
-            void CommandViewOnSelect (object sender, HandledEventArgs e)
-            {
-                // Always eat CommandView.Select
-                e.Handled = true;
-
-                // AND raise our Accept event
-                RaiseAcceptEvent ();
-            }
 
             SetCommandViewDefaultLayout ();
             SetHelpViewDefaultLayout ();
@@ -780,13 +780,20 @@ public class Shortcut : View, IOrientation, IDesignable
     /// </summary>
     protected bool? DispatchAcceptCommand (CommandContext ctx)
     {
+        if (RaiseSelectEvent () == true)
+        {
+            return true;
+        }
+
+        CommandView.InvokeCommand (Command.Select);
+
         var cancel = false;
 
-        bool? handled = CommandView.InvokeCommand (Command.Select, ctx.Key, ctx.KeyBinding);
+        cancel = RaiseAcceptEvent () == true;
 
-        if (handled is null or false)
+        if (cancel is true)
         {
-            cancel = RaiseAcceptEvent () == true;
+            return true;
         }
 
         if (Action is { })

+ 26 - 4
UICatalog/Scenarios/Buttons.cs

@@ -133,6 +133,7 @@ public class Buttons : Scenario
                       Text = "Lets see if this will move as \"Text Changer\" grows"
                   }
                  );
+        button.Accept += (sender, args) => { args.Handled = true; };
 
         var removeButton = new Button
         {
@@ -145,6 +146,7 @@ public class Buttons : Scenario
         removeButton.Accept += (s, e) =>
                                {
                                    removeButton.Visible = false;
+                                   e.Handled = true;
                                };
 
         var computedFrame = new FrameView
@@ -170,6 +172,7 @@ public class Buttons : Scenario
         moveBtn.Accept += (s, e) =>
                           {
                               moveBtn.X = moveBtn.Frame.X + 5;
+                              e.Handled = true;
                           };
         computedFrame.Add (moveBtn);
 
@@ -186,6 +189,7 @@ public class Buttons : Scenario
         sizeBtn.Accept += (s, e) =>
                           {
                               sizeBtn.Width = sizeBtn.Frame.Width + 5;
+                              e.Handled = true;
                           };
         computedFrame.Add (sizeBtn);
 
@@ -210,6 +214,7 @@ public class Buttons : Scenario
                                                      moveBtnA.Frame.Width,
                                                      moveBtnA.Frame.Height
                                                     );
+                               e.Handled = true;
                            };
         absoluteFrame.Add (moveBtnA);
 
@@ -227,6 +232,7 @@ public class Buttons : Scenario
                                                      sizeBtnA.Frame.Width + 5,
                                                      sizeBtnA.Frame.Height
                                                     );
+                               e.Handled = true;
                            };
         absoluteFrame.Add (sizeBtnA);
 
@@ -291,7 +297,11 @@ public class Buttons : Scenario
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
             Text = mhkb
         };
-        moveHotKeyBtn.Accept += (s, e) => { moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text); };
+        moveHotKeyBtn.Accept += (s, e) =>
+                                {
+                                    moveHotKeyBtn.Text = MoveHotkey (moveHotKeyBtn.Text);
+                                    e.Handled = true;
+                                };
         main.Add (moveHotKeyBtn);
 
         var muhkb = " ~  s  gui.cs   master ↑10 = Сохранить";
@@ -304,7 +314,11 @@ public class Buttons : Scenario
             ColorScheme = Colors.ColorSchemes ["TopLevel"],
             Text = muhkb
         };
-        moveUnicodeHotKeyBtn.Accept += (s, e) => { moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text); };
+        moveUnicodeHotKeyBtn.Accept += (s, e) =>
+                                       {
+                                           moveUnicodeHotKeyBtn.Text = MoveHotkey (moveUnicodeHotKeyBtn.Text);
+                                           e.Handled = true;
+                                       };
         main.Add (moveUnicodeHotKeyBtn);
 
         radioGroup.SelectedItemChanged += (s, args) =>
@@ -384,7 +398,11 @@ public class Buttons : Scenario
             Title = $"Accept Cou_nt: {noRepeatAcceptCount}",
             WantContinuousButtonPressed = false
         };
-        noRepeatButton.Accept += (s, e) => { noRepeatButton.Title = $"Accept Cou_nt: {++noRepeatAcceptCount}"; };
+        noRepeatButton.Accept += (s, e) =>
+                                 {
+                                     noRepeatButton.Title = $"Accept Cou_nt: {++noRepeatAcceptCount}";
+                                     e.Handled = true;
+                                 };
         main.Add (label, noRepeatButton);
 
         label = new ()
@@ -402,7 +420,11 @@ public class Buttons : Scenario
             Title = $"Accept Co_unt: {acceptCount}",
             WantContinuousButtonPressed = true
         };
-        repeatButton.Accept += (s, e) => { repeatButton.Title = $"Accept Co_unt: {++acceptCount}"; };
+        repeatButton.Accept += (s, e) =>
+                               {
+                                   repeatButton.Title = $"Accept Co_unt: {++acceptCount}";
+                                   e.Handled = true;
+                               };
 
         var enableCB = new CheckBox
         {

+ 1 - 1
UICatalog/Scenarios/Shortcuts.cs

@@ -358,7 +358,7 @@ public class Shortcuts : Scenario
                 {
                     eventSource.Add ($"{shortcut!.Id}.Select: {shortcut!.CommandView.Text} {shortcut!.CommandView.GetType ().Name}");
                     eventLog.MoveDown ();
-                    args.Handled = true;
+                    //args.Handled = true;
                 };
 
                 shortcut.CommandView.Select += (o, args) =>

+ 86 - 0
UnitTests/View/Adornment/AdornmentTests.cs

@@ -389,20 +389,106 @@ public class AdornmentTests (ITestOutputHelper output)
     [InlineData (0, 0, 0, 1, 0, 0, false)]
     [InlineData (0, 0, 1, 0, 0, 0, false)]
     [InlineData (0, 0, 1, 1, 0, 0, true)]
+    [InlineData (0, 0, 1, 2, 0, 0, true)]
 
     [InlineData (1, 1, 0, 0, 0, 0, false)]
     [InlineData (1, 1, 0, 1, 0, 0, false)]
     [InlineData (1, 1, 1, 0, 0, 0, false)]
     [InlineData (1, 1, 1, 0, 0, 1, false)]
     [InlineData (1, 1, 1, 1, 1, 0, false)]
+    [InlineData (1, 1, 1, 1, 0, 0, false)]
     [InlineData (1, 1, 1, 1, 1, 1, true)]
+    [InlineData (1, 1, 1, 2, 1, 1, true)]
     public void Contains_Left_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected)
     {
         Adornment adornment = new () { Id = "adornment" };
         adornment.Parent = new View () { Id = "parent" };
         adornment.Parent.Frame = new Rectangle (x, y, width, height);
         adornment.Thickness = new (1, 0, 0, 0);
+        adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty };
 
+        bool result = adornment.Contains (new (pointX, pointY));
+        Assert.Equal (expected, result);
+    }
+
+    [Theory]
+    [InlineData (0, 0, 0, 0, 0, 0, false)]
+    [InlineData (0, 0, 0, 1, 0, 0, false)]
+    [InlineData (0, 0, 1, 0, 0, 0, false)]
+    [InlineData (0, 0, 1, 1, 0, 0, true)]
+    [InlineData (0, 0, 1, 2, 0, 0, true)]
+
+    [InlineData (1, 1, 0, 0, 0, 0, false)]
+    [InlineData (1, 1, 0, 1, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 1, false)]
+    [InlineData (1, 1, 1, 1, 1, 0, false)]
+    [InlineData (1, 1, 1, 1, 0, 0, false)]
+    [InlineData (1, 1, 1, 1, 1, 1, true)]
+    [InlineData (1, 1, 1, 2, 1, 1, true)]
+    public void Contains_Right_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected)
+    {
+        Adornment adornment = new () { Id = "adornment" };
+        adornment.Parent = new View () { Id = "parent" };
+        adornment.Parent.Frame = new Rectangle (x, y, width, height);
+        adornment.Thickness = new (0, 0, 1, 0);
+        adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty };
+
+        bool result = adornment.Contains (new (pointX, pointY));
+        Assert.Equal (expected, result);
+    }
+
+
+    [Theory]
+    [InlineData (0, 0, 0, 0, 0, 0, false)]
+    [InlineData (0, 0, 0, 1, 0, 0, false)]
+    [InlineData (0, 0, 1, 0, 0, 0, false)]
+    [InlineData (0, 0, 1, 1, 0, 0, true)]
+    [InlineData (0, 0, 1, 2, 0, 0, true)]
+
+    [InlineData (1, 1, 0, 0, 0, 0, false)]
+    [InlineData (1, 1, 0, 1, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 1, false)]
+    [InlineData (1, 1, 1, 1, 1, 0, false)]
+    [InlineData (1, 1, 1, 1, 0, 0, false)]
+    [InlineData (1, 1, 1, 1, 1, 1, true)]
+    [InlineData (1, 1, 1, 2, 1, 1, true)]
+    public void Contains_Top_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected)
+    {
+        Adornment adornment = new () { Id = "adornment" };
+        adornment.Parent = new View () { Id = "parent" };
+        adornment.Parent.Frame = new Rectangle (x, y, width, height);
+        adornment.Thickness = new (0, 1, 0, 0);
+        adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty };
+
+        bool result = adornment.Contains (new (pointX, pointY));
+        Assert.Equal (expected, result);
+    }
+
+
+    [Theory]
+    [InlineData (0, 0, 0, 0, 0, 0, false)]
+    [InlineData (0, 0, 0, 1, 0, 0, false)]
+    [InlineData (0, 0, 1, 0, 0, 0, false)]
+    [InlineData (0, 0, 1, 1, 0, 0, true)]
+    [InlineData (0, 0, 1, 2, 0, 0, true)]
+
+    [InlineData (1, 1, 0, 0, 0, 0, false)]
+    [InlineData (1, 1, 0, 1, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 0, false)]
+    [InlineData (1, 1, 1, 0, 0, 1, false)]
+    [InlineData (1, 1, 1, 1, 1, 0, false)]
+    [InlineData (1, 1, 1, 1, 0, 0, false)]
+    [InlineData (1, 1, 1, 1, 1, 1, true)]
+    [InlineData (1, 1, 1, 2, 1, 1, true)]
+    public void Contains_TopLeft_Only (int x, int y, int width, int height, int pointX, int pointY, bool expected)
+    {
+        Adornment adornment = new () { Id = "adornment" };
+        adornment.Parent = new View () { Id = "parent" };
+        adornment.Parent.Frame = new Rectangle (x, y, width, height);
+        adornment.Thickness = new (1, 1, 0, 0);
+        adornment.Frame = adornment.Parent.Frame with { Location = Point.Empty };
 
         bool result = adornment.Contains (new (pointX, pointY));
         Assert.Equal (expected, result);

+ 2 - 2
UnitTests/View/Mouse/MouseTests.cs

@@ -74,9 +74,9 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews
         Application.Begin (top);
 
         Assert.Equal (new Point (4, 4), testView.Frame.Location);
-        Application.OnMouseEvent (new () { Position = new (xy, xy), Flags = MouseFlags.Button1Pressed });
+        Application.OnMouseEvent (new () { ScreenPosition = new (xy, xy), Flags = MouseFlags.Button1Pressed });
 
-        Application.OnMouseEvent (new () { Position = new (xy + 1, xy + 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
+        Application.OnMouseEvent (new () { ScreenPosition = new (xy + 1, xy + 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition });
 
         Assert.Equal (expectedMoved, new Point (5, 5) == testView.Frame.Location);
         top.Dispose ();

+ 18 - 2
UnitTests/View/ViewCommandTests.cs

@@ -116,14 +116,22 @@ public class ViewCommandTests (ITestOutputHelper output)
         Assert.Equal (6, subview.OnAcceptCount);
         Assert.Equal (3, view.OnAcceptCount);
         Assert.Equal (1, superView.OnAcceptCount);
+    }
 
+    [Fact]
+    public void MouseClick_Does_Not_Invoke_Accept_Command ()
+    {
+        var view = new ViewEventTester ();
+        view.NewMouseEvent (new () { Flags = MouseFlags.Button1Clicked, Position = Point.Empty, View = view });
+
+        Assert.Equal (0, view.OnAcceptCount);
     }
 
     #endregion OnAccept/Accept tests
 
     #region OnSelect/Select tests
     [Fact]
-    public void Select_Command_Raises_NoFocus ()
+    public void Select_Command_Raises_SetsFocus ()
     {
         var view = new ViewEventTester ();
         Assert.False (view.HasFocus);
@@ -134,7 +142,7 @@ public class ViewCommandTests (ITestOutputHelper output)
 
         Assert.Equal (1, view.SelectCount);
 
-        Assert.False (view.HasFocus);
+        Assert.True (view.HasFocus);
     }
 
     [Fact]
@@ -188,6 +196,14 @@ public class ViewCommandTests (ITestOutputHelper output)
         void ViewOnSelect (object sender, HandledEventArgs e) { Selected = true; }
     }
 
+    [Fact]
+    public void MouseClick_Invokes_Select_Command ()
+    {
+        var view = new ViewEventTester ();
+        view.NewMouseEvent (new () { Flags = MouseFlags.Button1Clicked, Position = Point.Empty, View = view });
+
+        Assert.Equal (1, view.OnSelectCount);
+    }
 
     #endregion OnSelect/Select tests
 

+ 0 - 21
UnitTests/Views/CheckBoxTests.cs

@@ -312,29 +312,8 @@ public class CheckBoxTests (ITestOutputHelper output)
         Assert.Equal (0, selectCount);
         Assert.Equal (0, acceptCount);
 
-#if !CHECKBOX_SUPPORTS_DOUBLE_CLICK_ACCEPT
-        Assert.False (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
-#else
-
         Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
-        Assert.Equal (CheckState.Checked, checkBox.CheckedState);
-        Assert.Equal (1, checkedStateChangingCount);
-        Assert.Equal (1, selectCount);
-        Assert.Equal (0, acceptCount);
 
-        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
-        Assert.Equal (CheckState.UnChecked, checkBox.CheckedState);
-        Assert.Equal (2, checkedStateChangingCount);
-        Assert.Equal (2, selectCount);
-        Assert.Equal (0, acceptCount);
-
-        checkBox.AllowCheckStateNone = true;
-        Assert.True (checkBox.NewMouseEvent (new () { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }));
-        Assert.Equal (CheckState.None, checkBox.CheckedState);
-        Assert.Equal (3, checkedStateChangingCount);
-        Assert.Equal (3, selectCount);
-        Assert.Equal (0, acceptCount);
-#endif
     }
 
 #endregion Mouse Tests

+ 12 - 1
UnitTests/Views/ShortcutTests.cs

@@ -445,7 +445,17 @@ public class ShortcutTests
     //  0123456789
     // " C  0  A "
     [InlineData (-1, 0, 0, 0, 0)]
-    [InlineData (0, 1, 0, 1, 1)]
+    [InlineData (0, 1, 0, 0, 1)] // mouseX = 0 is on the CommandView.Margin, so Shortcut will get MouseClick
+    [InlineData (1, 0, 0, 0, 1)] // mouseX = 1 is on the CommandView, so CommandView will get MouseClick
+    [InlineData (2, 1, 0, 0, 1)] // mouseX = 2 is on the CommandView.Margin, so Shortcut will get MouseClick
+    [InlineData (3, 0, 0, 0, 1)]
+    [InlineData (4, 0, 0, 0, 1)]
+    [InlineData (5, 0, 0, 1, 1)]
+    [InlineData (6, 0, 0, 1, 1)]
+    [InlineData (7, 0, 0, 1, 1)]
+    [InlineData (8, 0, 0, 1, 1)]
+    [InlineData (9, 0, 0, 0, 0)]
+
     //[InlineData (1, 1, 1)]
     //[InlineData (2, 1, 0)]
     //[InlineData (3, 1, 0)]
@@ -491,6 +501,7 @@ public class ShortcutTests
 
         Application.Top.Add (shortcut);
         Application.Top.SetRelativeLayout (new (100, 100));
+        Application.Top.LayoutSubviews();
 
         Application.OnMouseEvent (
                                   new ()