Browse Source

Fixes #3333. Application.UnGrabbedMouse event doesn't allow grab another view after exit.

BDisp 1 year ago
parent
commit
0120a3648f

+ 2 - 1
Terminal.Gui/Application.cs

@@ -1305,8 +1305,9 @@ public static partial class Application
 
         if (!OnUnGrabbingMouse (MouseGrabView))
         {
-            OnUnGrabbedMouse (MouseGrabView);
+            var view = MouseGrabView;
             MouseGrabView = null;
+            OnUnGrabbedMouse (view);
         }
     }
 

+ 14 - 0
Terminal.Gui/Views/ScrollView.cs

@@ -78,6 +78,8 @@ public class ScrollView : View
         _contentView.MouseEnter += View_MouseEnter;
         _contentView.MouseLeave += View_MouseLeave;
 
+        Application.UnGrabbedMouse += Application_UnGrabbedMouse;
+
         // Things this view knows how to do
         AddCommand (Command.ScrollUp, () => ScrollUp (1));
         AddCommand (Command.ScrollDown, () => ScrollDown (1));
@@ -134,6 +136,16 @@ public class ScrollView : View
                        };
     }
 
+    private void Application_UnGrabbedMouse (object sender, ViewEventArgs e)
+    {
+        var parent = e.View is Adornment adornment ? adornment.Parent : e.View;
+
+        if (parent is { } && _contentView.Subviews.Contains (parent))
+        {
+            Application.GrabMouse (this);
+        }
+    }
+
     /// <summary>If true the vertical/horizontal scroll bars won't be showed if it's not needed.</summary>
     public bool AutoHideScrollBars
     {
@@ -536,6 +548,8 @@ public class ScrollView : View
             _horizontal?.Dispose ();
         }
 
+        Application.UnGrabbedMouse -= Application_UnGrabbedMouse;
+
         base.Dispose (disposing);
     }
 

+ 11 - 2
UnitTests/Application/MouseTests.cs

@@ -316,8 +316,9 @@ public class MouseTests
         View grabView = null;
         var count = 0;
 
-        var view1 = new View ();
-        var view2 = new View ();
+        var view1 = new View { Id = "view1" };
+        var view2 = new View { Id = "view2" };
+        var view3 = new View { Id = "view3" };
 
         Application.GrabbedMouse += Application_GrabbedMouse;
         Application.UnGrabbedMouse += Application_UnGrabbedMouse;
@@ -343,6 +344,8 @@ public class MouseTests
         Application.UngrabMouse ();
         Assert.Equal (2, count);
         Assert.Equal (grabView, view2);
+        Assert.Equal (view3, Application.MouseGrabView);
+        Application.UngrabMouse ();
         Assert.Null (Application.MouseGrabView);
 
         void Application_GrabbedMouse (object sender, ViewEventArgs e)
@@ -376,6 +379,12 @@ public class MouseTests
 
             count++;
 
+            if (count > 1)
+            {
+                // It's possible to grab another view after the previous was ungrabbed
+                Application.GrabMouse (view3);
+            }
+
             Application.UnGrabbedMouse -= Application_UnGrabbedMouse;
         }
     }

+ 38 - 39
UnitTests/Views/ToplevelTests.cs

@@ -1366,7 +1366,6 @@ public class ToplevelTests
         Assert.Equal (new (0, 0, 10, 5), view._needsDisplayRect);
     }
 
-    // BUGBUG: Broke this test with #2483 - @bdisp I need your help figuring out why
     [Fact]
     [AutoInitShutdown]
     public void Toplevel_Inside_ScrollView_MouseGrabView ()
@@ -1471,44 +1470,44 @@ public class ToplevelTests
         Assert.Equal (win.Border, Application.MouseGrabView);
         top.SetNeedsLayout ();
         top.LayoutSubviews ();
-        // BUGBUG: tig broke this in #3273
-   //     Assert.Equal (new Rectangle (2, 2, 195, 95), win.Frame);
-   //     Application.Refresh ();
-
-   //     TestHelpers.AssertDriverContentsWithFrameAre (
-   //                                                   @"
-   //                                       ▲
-   //                                       ┬
-   //  ┌────────────────────────────────────
-   //  │                                    ┴
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ░
-   //  │                                    ▼
-   //◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
-   //                                                   _output
-   //                                                  );
-
-   //     Application.OnMouseEvent (
-   //                               new MouseEventEventArgs (
-   //                                                        new MouseEvent { X = 5, Y = 5, Flags = MouseFlags.Button1Released }
-   //                                                       )
-   //                              );
-   //     Assert.Null (Application.MouseGrabView);
-
-   //     Application.OnMouseEvent (
-   //                               new MouseEventEventArgs (
-   //                                                        new MouseEvent { X = 4, Y = 4, Flags = MouseFlags.ReportMousePosition }
-   //                                                       )
-   //                              );
-   //     Assert.Equal (scrollView, Application.MouseGrabView);
+        Assert.Equal (new Rectangle (2, 2, 195, 95), win.Frame);
+        Application.Refresh ();
+
+        TestHelpers.AssertDriverContentsWithFrameAre (
+                                                      @"
+   
+   
+     ┌────────────────────────────────────│
+     │
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ░
+     │                                    ▼
+   ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ",
+                                                      _output
+                                                     );
+
+        Application.OnMouseEvent (
+                                  new MouseEventEventArgs (
+                                                           new MouseEvent { X = 5, Y = 5, Flags = MouseFlags.Button1Released }
+                                                          )
+                                 );
+        // ScrollView always grab the mouse when the container's subview OnMouseEnter don't want grab the mouse
+        Assert.Equal (scrollView, Application.MouseGrabView);
+
+        Application.OnMouseEvent (
+                                  new MouseEventEventArgs (
+                                                           new MouseEvent { X = 4, Y = 4, Flags = MouseFlags.ReportMousePosition }
+                                                          )
+                                 );
+        Assert.Equal (scrollView, Application.MouseGrabView);
     }
 
     [Fact]