Browse Source

Moved Toplevel drag out of Toplevel into Adornment (but still only works for Toplevel)

Tig Kindel 1 year ago
parent
commit
4398ccade7

+ 33 - 34
Terminal.Gui/Application.cs

@@ -532,7 +532,7 @@ public static partial class Application
     ///     <see langword="null"/> if <see cref="Init"/> has already been called.
     /// </param>
     public static void Run<T> (Func<Exception, bool> errorHandler = null, ConsoleDriver driver = null)
-        where T : Toplevel, new ()
+        where T : Toplevel, new()
     {
         if (_initialized)
         {
@@ -1400,46 +1400,45 @@ public static partial class Application
             return;
         }
 
-        if (view is not Adornment)
+        if (MouseGrabView is { })
         {
-            if (MouseGrabView is { })
+            // If the mouse is grabbed, send the event to the view that grabbed it.
+            // The coordinates are relative to the Bounds of the view that grabbed the mouse.
+            Point newxy = MouseGrabView.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
+
+            var nme = new MouseEvent
             {
-                // If the mouse is grabbed, send the event to the view that grabbed it.
-                // The coordinates are relative to the Bounds of the view that grabbed the mouse.
-                Point newxy = MouseGrabView.ScreenToFrame (a.MouseEvent.X, a.MouseEvent.Y);
+                X = newxy.X,
+                Y = newxy.Y,
+                Flags = a.MouseEvent.Flags,
+                OfX = a.MouseEvent.X - newxy.X,
+                OfY = a.MouseEvent.Y - newxy.Y,
+                View = view
+            };
 
-                var nme = new MouseEvent
-                {
-                    X = newxy.X,
-                    Y = newxy.Y,
-                    Flags = a.MouseEvent.Flags,
-                    OfX = a.MouseEvent.X - newxy.X,
-                    OfY = a.MouseEvent.Y - newxy.Y,
-                    View = view
-                };
-
-                if (MouseGrabView.Bounds.Contains (nme.X, nme.Y) is false)
-                {
-                    // The mouse has moved outside the bounds of the view that
-                    // grabbed the mouse, so we tell the view that last got 
-                    // OnMouseEnter the mouse is leaving
-                    // BUGBUG: That sentence makes no sense. Either I'm missing something
-                    // or this logic is flawed.
-                    _mouseEnteredView?.OnMouseLeave (a.MouseEvent);
-                }
+            if (MouseGrabView.Bounds.Contains (nme.X, nme.Y) is false)
+            {
+                // The mouse has moved outside the bounds of the view that
+                // grabbed the mouse, so we tell the view that last got 
+                // OnMouseEnter the mouse is leaving
+                // BUGBUG: That sentence makes no sense. Either I'm missing something or this logic is flawed.
+                _mouseEnteredView?.OnMouseLeave (a.MouseEvent);
+            }
 
-                //System.Diagnostics.Debug.WriteLine ($"{nme.Flags};{nme.X};{nme.Y};{mouseGrabView}");
-                if (MouseGrabView?.OnMouseEvent (nme) == true)
-                {
-                    return;
-                }
+            //System.Diagnostics.Debug.WriteLine ($"{nme.Flags};{nme.X};{nme.Y};{mouseGrabView}");
+            if (MouseGrabView?.OnMouseEvent (nme) == true)
+            {
+                return;
             }
+        }
 
+        if (view is not Adornment)
+        {
             if ((view is null || view == OverlappedTop)
-                && Current is { Modal: false }
-                && OverlappedTop != null
-                && a.MouseEvent.Flags != MouseFlags.ReportMousePosition
-                && a.MouseEvent.Flags != 0)
+                    && Current is { Modal: false }
+                    && OverlappedTop != null
+                    && a.MouseEvent.Flags != MouseFlags.ReportMousePosition
+                    && a.MouseEvent.Flags != 0)
             {
                 // This occurs when there are multiple overlapped "tops"
                 // E.g. "Mdi" - in the Background Worker Scenario

+ 100 - 10
Terminal.Gui/View/Adornment/Adornment.cs

@@ -28,7 +28,14 @@ public class Adornment : View
 
     /// <summary>Constructs a new adornment for the view specified by <paramref name="parent"/>.</summary>
     /// <param name="parent"></param>
-    public Adornment (View parent) { Parent = parent; }
+    public Adornment (View parent)
+    {
+
+        Application.GrabbingMouse += Application_GrabbingMouse;
+        Application.UnGrabbingMouse += Application_UnGrabbingMouse;
+
+        Parent = parent;
+    }
 
     /// <summary>Gets the rectangle that describes the inner area of the Adornment. The Location is always (0,0).</summary>
     public override Rectangle Bounds
@@ -166,13 +173,9 @@ public class Adornment : View
     /// <summary>Fired whenever the <see cref="Thickness"/> property changes.</summary>
     public event EventHandler<ThicknessEventArgs> ThicknessChanged;
 
-    /// <inheritdoc/>
-    protected internal override bool OnMouseEnter (MouseEvent mouseEvent)
-    {
-        var args = new MouseEventEventArgs (mouseEvent);
+    internal static Point? _dragPosition;
 
-        return args.Handled || base.OnMouseEnter (mouseEvent);
-    }
+    private Point _startGrabPoint;
 
     /// <inheritdoc/>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
@@ -190,15 +193,102 @@ public class Adornment : View
             return OnMouseClick (args);
         }
 
+        // TODO: Checking for Toplevel is a hack until #2537 is fixed
+        if (!Parent.CanFocus || Parent is not Toplevel)
+        {
+            return true;
+        }
+
+        //System.Diagnostics.Debug.WriteLine ($"dragPosition before: {dragPosition.HasValue}");
+
+        int nx, ny;
+
+        if (!_dragPosition.HasValue
+            && (mouseEvent.Flags.HasFlag(MouseFlags.Button1Pressed)
+                || mouseEvent.Flags.HasFlag(MouseFlags.Button2Pressed)
+                || mouseEvent.Flags.HasFlag(MouseFlags.Button3Pressed)))
+        {
+            Parent.SetFocus ();
+            Application.BringOverlappedTopToFront ();
+
+            // Only start grabbing if the user clicks on the title bar.
+            if (mouseEvent.Y == 0 && mouseEvent.Flags.HasFlag(MouseFlags.Button1Pressed))
+            {
+                _startGrabPoint = new Point (mouseEvent.X, mouseEvent.Y);
+                nx = mouseEvent.X - mouseEvent.OfX;
+                ny = mouseEvent.Y - mouseEvent.OfY;
+                _dragPosition = new Point (nx, ny);
+                Application.GrabMouse (this);
+            }
+
+            //System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
+            return true;
+        }
+
+        if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) || mouseEvent.Flags == MouseFlags.Button3Pressed)
+        {
+            if (_dragPosition.HasValue)
+            {
+                if (Parent.SuperView is null)
+                {
+                    // Redraw the entire app window.
+                    Application.Top.SetNeedsDisplay ();
+                }
+                else
+                {
+                    Parent.SuperView.SetNeedsDisplay ();
+                }
+
+                View.GetLocationThatFits (
+                                     Parent,
+                                     mouseEvent.X + mouseEvent.OfX - _startGrabPoint.X,
+                                     mouseEvent.Y + mouseEvent.OfY - _startGrabPoint.Y,
+                                     out nx,
+                                     out ny,
+                                     out _,
+                                     out _
+                                    );
+
+                _dragPosition = new Point (nx, ny);
+                Parent.X = nx;
+                Parent.Y = ny;
+                Parent.SetNeedsDisplay ();
+                return true;
+            }
+        }
+
+        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) && _dragPosition.HasValue)
+        {
+            _dragPosition = null;
+            Application.UngrabMouse ();
+        }
         return false;
     }
 
+    private void Application_GrabbingMouse (object sender, GrabMouseEventArgs e)
+    {
+        if (Application.MouseGrabView == this && _dragPosition.HasValue)
+        {
+            e.Cancel = true;
+        }
+    }
+
+    private void Application_UnGrabbingMouse (object sender, GrabMouseEventArgs e)
+    {
+        if (Application.MouseGrabView == this && _dragPosition.HasValue)
+        {
+            e.Cancel = true;
+        }
+    }
+
     /// <inheritdoc/>
-    protected internal override bool OnMouseLeave (MouseEvent mouseEvent)
+    protected override void Dispose (bool disposing)
     {
-        var args = new MouseEventEventArgs (mouseEvent);
+        Application.GrabbingMouse -= Application_GrabbingMouse;
+        Application.UnGrabbingMouse -= Application_UnGrabbingMouse;
 
-        return args.Handled || base.OnMouseLeave (mouseEvent);
+        _dragPosition = null;
+        base.Dispose (disposing);
     }
 
     internal override Adornment CreateAdornment (Type adornmentType)

+ 7 - 0
Terminal.Gui/View/Adornment/Padding.cs

@@ -38,4 +38,11 @@ public class Padding : Adornment
             Parent?.SetNeedsDisplay ();
         }
     }
+
+    /// <inheritdoc/>
+    protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
+    {
+        return false;
+    }
+
 }

+ 149 - 0
Terminal.Gui/View/Layout/ViewLayout.cs

@@ -1504,4 +1504,153 @@ public partial class View
 #endif // DEBUG
         return pos;
     }
+
+
+    /// <summary>
+    ///     Gets a new location of the <see cref="View"/> that is within the Bounds of the <paramref name="top"/>'s
+    ///     <see cref="View.SuperView"/> (e.g. for dragging a Window). The `out` parameters are the new X and Y coordinates.
+    /// </summary>
+    /// <remarks>
+    ///     If <paramref name="top"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not
+    ///     <see cref="Application.Top"/> the position will be bound by the <see cref="ConsoleDriver.Cols"/> and
+    ///     <see cref="ConsoleDriver.Rows"/>.
+    /// </remarks>
+    /// <param name="top">The View that is to be moved.</param>
+    /// <param name="targetX">The target x location.</param>
+    /// <param name="targetY">The target y location.</param>
+    /// <param name="nx">The x location that will ensure <paramref name="top"/> will be visible.</param>
+    /// <param name="ny">The y location that will ensure <paramref name="top"/> will be visible.</param>
+    /// <param name="menuBar">The new top most menuBar</param>
+    /// <param name="statusBar">The new top most statusBar</param>
+    /// <returns>
+    ///     Either <see cref="Application.Top"/> (if <paramref name="top"/> does not have a Super View) or
+    ///     <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the correct View.
+    /// </returns>
+    internal static View GetLocationThatFits (
+        View top,
+        int targetX,
+        int targetY,
+        out int nx,
+        out int ny,
+        out MenuBar menuBar,
+        out StatusBar statusBar
+    )
+    {
+        int maxWidth;
+        View superView;
+
+        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
+        {
+            maxWidth = Driver.Cols;
+            superView = Application.Top;
+        }
+        else
+        {
+            // Use the SuperView's Bounds, not Frame
+            maxWidth = top.SuperView.Bounds.Width;
+            superView = top.SuperView;
+        }
+
+        if (superView.Margin is { } && superView == top.SuperView)
+        {
+            maxWidth -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
+        }
+
+        if (top.Frame.Width <= maxWidth)
+        {
+            nx = Math.Max (targetX, 0);
+            nx = nx + top.Frame.Width > maxWidth ? Math.Max (maxWidth - top.Frame.Width, 0) : nx;
+
+            if (nx > top.Frame.X + top.Frame.Width)
+            {
+                nx = Math.Max (top.Frame.Right, 0);
+            }
+        }
+        else
+        {
+            nx = targetX;
+        }
+
+        //System.Diagnostics.Debug.WriteLine ($"nx:{nx}, rWidth:{rWidth}");
+        bool menuVisible, statusVisible;
+
+        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
+        {
+            menuVisible = Application.Top.MenuBar?.Visible == true;
+            menuBar = Application.Top.MenuBar;
+        }
+        else
+        {
+            View t = top.SuperView;
+
+            while (t is not Toplevel)
+            {
+                t = t.SuperView;
+            }
+
+            menuVisible = ((Toplevel)t).MenuBar?.Visible == true;
+            menuBar = ((Toplevel)t).MenuBar;
+        }
+
+        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
+        {
+            maxWidth = menuVisible ? 1 : 0;
+        }
+        else
+        {
+            maxWidth = 0;
+        }
+
+        ny = Math.Max (targetY, maxWidth);
+
+        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
+        {
+            statusVisible = Application.Top.StatusBar?.Visible == true;
+            statusBar = Application.Top.StatusBar;
+        }
+        else
+        {
+            View t = top.SuperView;
+
+            while (t is not Toplevel)
+            {
+                t = t.SuperView;
+            }
+
+            statusVisible = ((Toplevel)t).StatusBar?.Visible == true;
+            statusBar = ((Toplevel)t).StatusBar;
+        }
+
+        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
+        {
+            maxWidth = statusVisible ? Driver.Rows - 1 : Driver.Rows;
+        }
+        else
+        {
+            maxWidth = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height;
+        }
+
+        if (superView.Margin is { } && superView == top.SuperView)
+        {
+            maxWidth -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
+        }
+
+        ny = Math.Min (ny, maxWidth);
+
+        if (top.Frame.Height <= maxWidth)
+        {
+            ny = ny + top.Frame.Height > maxWidth
+                     ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0)
+                     : ny;
+
+            if (ny > top.Frame.Y + top.Frame.Height)
+            {
+                ny = Math.Max (top.Frame.Bottom, 0);
+            }
+        }
+
+        //System.Diagnostics.Debug.WriteLine ($"ny:{ny}, rHeight:{rHeight}");
+
+        return superView;
+    }
 }

+ 1 - 280
Terminal.Gui/Views/Toplevel.cs

@@ -20,10 +20,6 @@ namespace Terminal.Gui;
 /// </remarks>
 public partial class Toplevel : View
 {
-    internal static Point? _dragPosition;
-
-    private Point _startGrabPoint;
-
     /// <summary>
     ///     Initializes a new instance of the <see cref="Toplevel"/> class with <see cref="LayoutStyle.Computed"/> layout,
     ///     defaulting to full screen. The <see cref="View.Width"/> and <see cref="View.Height"/> properties will be set to the
@@ -36,13 +32,6 @@ public partial class Toplevel : View
 
         ColorScheme = Colors.ColorSchemes ["TopLevel"];
 
-        Application.GrabbingMouse += Application_GrabbingMouse;
-        Application.UnGrabbingMouse += Application_UnGrabbingMouse;
-
-        // TODO: v2 - ALL Views (Responders??!?!) should support the commands related to 
-        //    - Focus
-        //  Move the appropriate AddCommand calls to `Responder`
-
         // Things this view knows how to do
         AddCommand (
                     Command.QuitToplevel,
@@ -236,100 +225,6 @@ public partial class Toplevel : View
     /// </summary>
     public event EventHandler Loaded;
 
-    /// <inheritdoc/>
-    protected internal override bool OnMouseEvent  (MouseEvent mouseEvent)
-    {
-        if (!CanFocus)
-        {
-            return true;
-        }
-
-        //System.Diagnostics.Debug.WriteLine ($"dragPosition before: {dragPosition.HasValue}");
-
-        int nx, ny;
-
-        if (!_dragPosition.HasValue
-            && (mouseEvent.Flags == MouseFlags.Button1Pressed
-                || mouseEvent.Flags == MouseFlags.Button2Pressed
-                || mouseEvent.Flags == MouseFlags.Button3Pressed))
-        {
-            SetFocus ();
-            Application.BringOverlappedTopToFront ();
-
-            // Only start grabbing if the user clicks on the title bar.
-            // BUGBUG: Assumes Frame == Border and Title is always at Y == 0
-            if (mouseEvent.Y == 0 && mouseEvent.Flags == MouseFlags.Button1Pressed)
-            {
-                _startGrabPoint = new Point (mouseEvent.X, mouseEvent.Y);
-                _dragPosition = Point.Empty;
-                nx = mouseEvent.X - mouseEvent.OfX;
-                ny = mouseEvent.Y - mouseEvent.OfY;
-                _dragPosition = new Point (nx, ny);
-                Application.GrabMouse (this);
-            }
-
-            //System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
-            return true;
-        }
-
-        if (mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) || mouseEvent.Flags == MouseFlags.Button3Pressed)
-        {
-            if (_dragPosition.HasValue)
-            {
-                if (SuperView is null)
-                {
-                    // Redraw the entire app window using just our Frame. Since we are 
-                    // Application.Top, and our Frame always == our Bounds (Location is always (0,0))
-                    // our Frame is actually view-relative (which is what Redraw takes).
-                    // We need to pass all the view bounds because since the windows was 
-                    // moved around, we don't know exactly what was the affected region.
-                    Application.Top.SetNeedsDisplay ();
-                }
-                else
-                {
-                    SuperView.SetNeedsDisplay ();
-                }
-
-                // BUGBUG: Assumes Frame == Border?
-                GetLocationThatFits (
-                                     this,
-                                     mouseEvent.X
-                                     + (SuperView == null
-                                            ? mouseEvent.OfX - _startGrabPoint.X
-                                            : Frame.X - _startGrabPoint.X),
-                                     mouseEvent.Y
-                                     + (SuperView == null
-                                            ? mouseEvent.OfY - _startGrabPoint.Y
-                                            : Frame.Y - _startGrabPoint.Y),
-                                     out nx,
-                                     out ny,
-                                     out _,
-                                     out _
-                                    );
-
-                _dragPosition = new Point (nx, ny);
-                X = nx;
-                Y = ny;
-
-                //System.Diagnostics.Debug.WriteLine ($"Drag: nx:{nx},ny:{ny}");
-
-                SetNeedsDisplay ();
-
-                return true;
-            }
-        }
-
-        if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) && _dragPosition.HasValue)
-        {
-            _dragPosition = null;
-            Application.UngrabMouse ();
-        }
-
-        //System.Diagnostics.Debug.WriteLine ($"dragPosition after: {dragPosition.HasValue}");
-        //System.Diagnostics.Debug.WriteLine ($"Toplevel: {mouseEvent}");
-        return false;
-    }
-
     /// <summary>Virtual method to invoke the <see cref="AlternateBackwardKeyChanged"/> event.</summary>
     /// <param name="e"></param>
     public virtual void OnAlternateBackwardKeyChanged (KeyChangedEventArgs e)
@@ -646,17 +541,7 @@ public partial class Toplevel : View
     ///     to dispose objects after calling <see cref="Application.End(RunState)"/>.
     /// </summary>
     public event EventHandler Unloaded;
-
-    /// <inheritdoc/>
-    protected override void Dispose (bool disposing)
-    {
-        Application.GrabbingMouse -= Application_GrabbingMouse;
-        Application.UnGrabbingMouse -= Application_UnGrabbingMouse;
-
-        _dragPosition = null;
-        base.Dispose (disposing);
-    }
-
+    
     internal void AddMenuStatusBar (View view)
     {
         if (view is MenuBar)
@@ -670,154 +555,6 @@ public partial class Toplevel : View
         }
     }
 
-    /// <summary>
-    ///     Gets a new location of the <see cref="Toplevel"/> that is within the Bounds of the <paramref name="top"/>'s
-    ///     <see cref="View.SuperView"/> (e.g. for dragging a Window). The `out` parameters are the new X and Y coordinates.
-    /// </summary>
-    /// <remarks>
-    ///     If <paramref name="top"/> does not have a <see cref="View.SuperView"/> or it's SuperView is not
-    ///     <see cref="Application.Top"/> the position will be bound by the <see cref="ConsoleDriver.Cols"/> and
-    ///     <see cref="ConsoleDriver.Rows"/>.
-    /// </remarks>
-    /// <param name="top">The Toplevel that is to be moved.</param>
-    /// <param name="targetX">The target x location.</param>
-    /// <param name="targetY">The target y location.</param>
-    /// <param name="nx">The x location that will ensure <paramref name="top"/> will be visible.</param>
-    /// <param name="ny">The y location that will ensure <paramref name="top"/> will be visible.</param>
-    /// <param name="menuBar">The new top most menuBar</param>
-    /// <param name="statusBar">The new top most statusBar</param>
-    /// <returns>
-    ///     Either <see cref="Application.Top"/> (if <paramref name="top"/> does not have a Super View) or
-    ///     <paramref name="top"/>'s SuperView. This can be used to ensure LayoutSubviews is called on the correct View.
-    /// </returns>
-    internal View GetLocationThatFits (
-        Toplevel top,
-        int targetX,
-        int targetY,
-        out int nx,
-        out int ny,
-        out MenuBar menuBar,
-        out StatusBar statusBar
-    )
-    {
-        int maxWidth;
-        View superView;
-
-        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
-        {
-            maxWidth = Driver.Cols;
-            superView = Application.Top;
-        }
-        else
-        {
-            // Use the SuperView's Bounds, not Frame
-            maxWidth = top.SuperView.Bounds.Width;
-            superView = top.SuperView;
-        }
-
-        if (superView.Margin is { } && superView == top.SuperView)
-        {
-            maxWidth -= superView.GetAdornmentsThickness ().Left + superView.GetAdornmentsThickness ().Right;
-        }
-
-        if (top.Frame.Width <= maxWidth)
-        {
-            nx = Math.Max (targetX, 0);
-            nx = nx + top.Frame.Width > maxWidth ? Math.Max (maxWidth - top.Frame.Width, 0) : nx;
-
-            if (nx > top.Frame.X + top.Frame.Width)
-            {
-                nx = Math.Max (top.Frame.Right, 0);
-            }
-        }
-        else
-        {
-            nx = targetX;
-        }
-
-        //System.Diagnostics.Debug.WriteLine ($"nx:{nx}, rWidth:{rWidth}");
-        bool menuVisible, statusVisible;
-
-        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
-        {
-            menuVisible = Application.Top.MenuBar?.Visible == true;
-            menuBar = Application.Top.MenuBar;
-        }
-        else
-        {
-            View t = top.SuperView;
-
-            while (t is not Toplevel)
-            {
-                t = t.SuperView;
-            }
-
-            menuVisible = ((Toplevel)t).MenuBar?.Visible == true;
-            menuBar = ((Toplevel)t).MenuBar;
-        }
-
-        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
-        {
-            maxWidth = menuVisible ? 1 : 0;
-        }
-        else
-        {
-            maxWidth = 0;
-        }
-
-        ny = Math.Max (targetY, maxWidth);
-
-        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
-        {
-            statusVisible = Application.Top.StatusBar?.Visible == true;
-            statusBar = Application.Top.StatusBar;
-        }
-        else
-        {
-            View t = top.SuperView;
-
-            while (t is not Toplevel)
-            {
-                t = t.SuperView;
-            }
-
-            statusVisible = ((Toplevel)t).StatusBar?.Visible == true;
-            statusBar = ((Toplevel)t).StatusBar;
-        }
-
-        if (top?.SuperView is null || top == Application.Top || top?.SuperView == Application.Top)
-        {
-            maxWidth = statusVisible ? Driver.Rows - 1 : Driver.Rows;
-        }
-        else
-        {
-            maxWidth = statusVisible ? top.SuperView.Frame.Height - 1 : top.SuperView.Frame.Height;
-        }
-
-        if (superView.Margin is { } && superView == top.SuperView)
-        {
-            maxWidth -= superView.GetAdornmentsThickness ().Top + superView.GetAdornmentsThickness ().Bottom;
-        }
-
-        ny = Math.Min (ny, maxWidth);
-
-        if (top.Frame.Height <= maxWidth)
-        {
-            ny = ny + top.Frame.Height > maxWidth
-                     ? Math.Max (maxWidth - top.Frame.Height, menuVisible ? 1 : 0)
-                     : ny;
-
-            if (ny > top.Frame.Y + top.Frame.Height)
-            {
-                ny = Math.Max (top.Frame.Bottom, 0);
-            }
-        }
-
-        //System.Diagnostics.Debug.WriteLine ($"ny:{ny}, rHeight:{rHeight}");
-
-        return superView;
-    }
-
     internal virtual void OnActivate (Toplevel deactivated) { Activate?.Invoke (this, new ToplevelEventArgs (deactivated)); }
     internal virtual void OnAllChildClosed () { AllChildClosed?.Invoke (this, EventArgs.Empty); }
 
@@ -901,22 +638,6 @@ public partial class Toplevel : View
         }
     }
 
-    private void Application_GrabbingMouse (object sender, GrabMouseEventArgs e)
-    {
-        if (Application.MouseGrabView == this && _dragPosition.HasValue)
-        {
-            e.Cancel = true;
-        }
-    }
-
-    private void Application_UnGrabbingMouse (object sender, GrabMouseEventArgs e)
-    {
-        if (Application.MouseGrabView == this && _dragPosition.HasValue)
-        {
-            e.Cancel = true;
-        }
-    }
-
     private void FocusNearestView (IEnumerable<View> views, NavigationDirection direction)
     {
         if (views is null)

+ 2 - 2
UnitTests/Application/KeyboardTests.cs

@@ -179,7 +179,7 @@ public class KeyboardTests
         Assert.True (win2.HasFocus);
         Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
         win2.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Released });
-        Assert.Null (Toplevel._dragPosition);
+        //Assert.Null (Toplevel._dragPosition);
     }
 
     [Fact]
@@ -240,7 +240,7 @@ public class KeyboardTests
         Assert.True (win2.HasFocus);
         Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title);
         win2.OnMouseEvent (new MouseEvent { Flags = MouseFlags.Button1Released });
-        Assert.Null (Toplevel._dragPosition);
+        //Assert.Null (Toplevel._dragPosition);
     }
 
     [Fact]

+ 16 - 16
UnitTests/Views/ToplevelTests.cs

@@ -256,7 +256,7 @@ public class ToplevelTests
         Assert.Equal (top, Application.Top);
 
         // Application.Top without menu and status bar.
-        View supView = top.GetLocationThatFits (top, 2, 2, out int nx, out int ny, out MenuBar mb, out StatusBar sb);
+        View supView = View.GetLocationThatFits (top, 2, 2, out int nx, out int ny, out MenuBar mb, out StatusBar sb);
         Assert.Equal (Application.Top, supView);
         Assert.Equal (0, nx);
         Assert.Equal (0, ny);
@@ -267,7 +267,7 @@ public class ToplevelTests
         Assert.NotNull (top.MenuBar);
 
         // Application.Top with a menu and without status bar.
-        top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
         Assert.Equal (1, ny);
         Assert.NotNull (mb);
@@ -277,7 +277,7 @@ public class ToplevelTests
         Assert.NotNull (top.StatusBar);
 
         // Application.Top with a menu and status bar.
-        top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
 
         // The available height is lower than the Application.Top height minus
@@ -290,7 +290,7 @@ public class ToplevelTests
         Assert.Null (top.MenuBar);
 
         // Application.Top without a menu and with a status bar.
-        top.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (top, 2, 2, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
 
         // The available height is lower than the Application.Top height minus
@@ -308,13 +308,13 @@ public class ToplevelTests
         top.LayoutSubviews ();
 
         // The SuperView is always the same regardless of the caller.
-        supView = top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
+        supView = View.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
         Assert.Equal (Application.Top, supView);
-        supView = win.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
+        supView = View.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
         Assert.Equal (Application.Top, supView);
 
         // Application.Top without menu and status bar.
-        top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
         Assert.Equal (0, ny);
         Assert.Null (mb);
@@ -324,7 +324,7 @@ public class ToplevelTests
         Assert.NotNull (top.MenuBar);
 
         // Application.Top with a menu and without status bar.
-        top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
         Assert.Equal (1, ny);
         Assert.NotNull (mb);
@@ -334,7 +334,7 @@ public class ToplevelTests
         Assert.NotNull (top.StatusBar);
 
         // Application.Top with a menu and status bar.
-        top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
 
         // The available height is lower than the Application.Top height minus
@@ -354,7 +354,7 @@ public class ToplevelTests
         top.Add (win);
 
         // Application.Top without menu and status bar.
-        top.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (win, 0, 0, out nx, out ny, out mb, out sb);
         Assert.Equal (0, nx);
         Assert.Equal (0, ny);
         Assert.Null (mb);
@@ -364,7 +364,7 @@ public class ToplevelTests
         Assert.NotNull (top.MenuBar);
 
         // Application.Top with a menu and without status bar.
-        top.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (win, 2, 2, out nx, out ny, out mb, out sb);
         Assert.Equal (2, nx);
         Assert.Equal (2, ny);
         Assert.NotNull (mb);
@@ -374,7 +374,7 @@ public class ToplevelTests
         Assert.NotNull (top.StatusBar);
 
         // Application.Top with a menu and status bar.
-        top.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
+        View.GetLocationThatFits (win, 30, 20, out nx, out ny, out mb, out sb);
         Assert.Equal (20, nx); // 20+60=80
         Assert.Equal (9, ny); // 9+15+1(mb)=25
         Assert.NotNull (mb);
@@ -383,14 +383,14 @@ public class ToplevelTests
         top.PositionToplevels ();
         Assert.Equal (new Rectangle (0, 1, 60, 15), win.Frame);
 
-        Assert.Null (Toplevel._dragPosition);
+        //Assert.Null (Toplevel._dragPosition);
         win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
-        Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
+       // Assert.Equal (new Point (6, 0), Toplevel._dragPosition);
         win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Released });
-        Assert.Null (Toplevel._dragPosition);
+        //Assert.Null (Toplevel._dragPosition);
         win.CanFocus = false;
         win.OnMouseEvent (new MouseEvent { X = 6, Y = 0, Flags = MouseFlags.Button1Pressed });
-        Assert.Null (Toplevel._dragPosition);
+        //Assert.Null (Toplevel._dragPosition);
     }
 
     [Fact]