Browse Source

Implement @tig scroll bars and fix some bugs.

BDisp 11 tháng trước cách đây
mục cha
commit
8d346a8d5c

+ 167 - 0
Terminal.Gui/View/View.ScrollBars.cs

@@ -0,0 +1,167 @@
+#nullable enable
+namespace Terminal.Gui;
+
+public partial class View
+{
+    private Lazy<ScrollBar> _horizontalScrollBar;
+    private Lazy<ScrollBar> _verticalScrollBar;
+
+    /// <summary>
+    ///     Initializes the ScrollBars of the View. Called by the constructor.
+    /// </summary>
+    private void SetupScrollBars ()
+    {
+        _horizontalScrollBar = new (
+                                    () =>
+                                    {
+                                        var scrollBar = new ScrollBar
+                                        {
+                                            Orientation = Orientation.Horizontal,
+                                            X = 0,
+                                            Y = Pos.AnchorEnd (),
+                                            Width = Dim.Fill (
+                                                              Dim.Func (
+                                                                        () =>
+                                                                        {
+                                                                            if (_verticalScrollBar.IsValueCreated)
+                                                                            {
+                                                                                return _verticalScrollBar.Value.Visible ? 1 : 0;
+                                                                            }
+
+                                                                            return 0;
+                                                                        })),
+                                            Size = GetContentSize ().Width,
+                                            Visible = false
+                                        };
+
+                                        Padding?.Add (scrollBar);
+
+                                        scrollBar.Initialized += (sender, args) =>
+                                        {
+                                            Padding.Thickness = Padding.Thickness with
+                                            {
+                                                Bottom = scrollBar.Visible ? Padding.Thickness.Bottom + 1 : 0
+                                            };
+
+                                            scrollBar.PositionChanged += (sender, args) =>
+                                            {
+                                                Viewport = Viewport with { X = args.CurrentValue };
+                                            };
+
+                                            scrollBar.VisibleChanged += (sender, args) =>
+                                            {
+                                                Padding.Thickness = Padding.Thickness with
+                                                {
+                                                    Bottom = scrollBar.Visible
+                                                        ? Padding.Thickness.Bottom + 1
+                                                        : Padding.Thickness.Bottom - 1
+                                                };
+                                            };
+                                        };
+
+                                        return scrollBar;
+                                    });
+
+        _verticalScrollBar = new (
+                                  () =>
+                                  {
+                                      var scrollBar = new ScrollBar
+                                      {
+                                          Orientation = Orientation.Vertical,
+                                          X = Pos.AnchorEnd (),
+                                          Y = Pos.Func (() => Padding.Thickness.Top),
+                                          Height = Dim.Fill (
+                                                             Dim.Func (
+                                                                       () =>
+                                                                       {
+                                                                           if (_horizontalScrollBar.IsValueCreated)
+                                                                           {
+                                                                               return _horizontalScrollBar.Value.Visible ? 1 : 0;
+                                                                           }
+
+                                                                           return 0;
+                                                                       })),
+                                          Size = GetContentSize ().Height,
+                                          Visible = false
+                                      };
+
+                                      Padding?.Add (scrollBar);
+
+                                      scrollBar.Initialized += (sender, args) =>
+                                      {
+                                          Padding.Thickness = Padding.Thickness with
+                                          {
+                                              Right = scrollBar.Visible ? Padding.Thickness.Right + 1 : 0
+                                          };
+
+                                          scrollBar.PositionChanged += (sender, args) =>
+                                          {
+                                              Viewport = Viewport with { Y = args.CurrentValue };
+                                          };
+
+                                          scrollBar.VisibleChanged += (sender, args) =>
+                                          {
+                                              Padding.Thickness = Padding.Thickness with
+                                              {
+                                                  Right = scrollBar.Visible
+                                                      ? Padding.Thickness.Right + 1
+                                                      : Padding.Thickness.Right - 1
+                                              };
+                                          };
+                                      };
+
+                                      return scrollBar;
+                                  });
+
+        ViewportChanged += (sender, args) =>
+        {
+            if (_verticalScrollBar.IsValueCreated)
+            {
+                _verticalScrollBar.Value.Position = Viewport.Y;
+            }
+
+            if (_horizontalScrollBar.IsValueCreated)
+            {
+                _horizontalScrollBar.Value.Position = Viewport.X;
+            }
+        };
+
+        ContentSizeChanged += (sender, args) =>
+        {
+            if (_verticalScrollBar.IsValueCreated)
+            {
+                _verticalScrollBar.Value.Size = GetContentSize ().Height;
+            }
+            if (_horizontalScrollBar.IsValueCreated)
+            {
+                _horizontalScrollBar.Value.Size = GetContentSize ().Width;
+            }
+        };
+    }
+
+    /// <summary>
+    /// </summary>
+    public ScrollBar? HorizontalScrollBar => _horizontalScrollBar.Value;
+
+    /// <summary>
+    /// </summary>
+    public ScrollBar? VerticalScrollBar => _verticalScrollBar.Value;
+
+    /// <summary>
+    ///     Clean up the ScrollBars of the View. Called by View.Dispose.
+    /// </summary>
+    private void DisposeScrollBars ()
+    {
+        if (_horizontalScrollBar.IsValueCreated)
+        {
+            Padding?.Remove (_horizontalScrollBar.Value);
+            _horizontalScrollBar.Value.Dispose ();
+        }
+
+        if (_verticalScrollBar.IsValueCreated)
+        {
+            Padding?.Remove (_verticalScrollBar.Value);
+            _verticalScrollBar.Value.Dispose ();
+        }
+    }
+}

+ 3 - 0
Terminal.Gui/View/View.cs

@@ -135,6 +135,7 @@ public partial class View : Responder, ISupportInitializeNotification
 
         DisposeKeyboard ();
         DisposeAdornments ();
+        DisposeScrollBars ();
 
         for (int i = InternalSubviews.Count - 1; i >= 0; i--)
         {
@@ -185,6 +186,8 @@ public partial class View : Responder, ISupportInitializeNotification
 
         //SetupMouse ();
         SetupText ();
+
+        SetupScrollBars ();
     }
 
     /// <summary>

+ 2 - 2
Terminal.Gui/Views/Scroll/Scroll.cs

@@ -33,7 +33,7 @@ public class Scroll : View
     private Orientation _orientation;
     private int _position;
     private int _size;
-    private bool _keepContentInAllViewport = true;
+    private bool _keepContentInAllViewport;
 
     /// <inheritdoc/>
     public override void EndInit ()
@@ -251,7 +251,7 @@ public class Scroll : View
     {
         int barSize = BarSize;
 
-        if (position + barSize > Size)
+        if (position + barSize > Size + (KeepContentInAllViewport ? 0 : barSize))
         {
             return KeepContentInAllViewport ? Math.Max (Size - barSize, 0) : Math.Max (Size - 1, 0);
         }

+ 36 - 13
Terminal.Gui/Views/Scroll/ScrollSlider.cs

@@ -91,18 +91,19 @@ internal class ScrollSlider : View
             {
                 Y = Frame.Y + offset < 0
                         ? 0
-                        :
-                        Frame.Y + offset + Frame.Height > barSize + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : barSize)
-                            ?
-                            Math.Max (barSize - Frame.Height, 0)
+                        : Frame.Y + offset + Frame.Height > barSize
+                            ? Math.Max (barSize - Frame.Height, 0)
                             : Frame.Y + offset;
 
                 SuperViewAsScroll.Position = GetPositionFromSliderLocation (Frame.Y);
             }
             else
             {
-                X = Frame.X + offset < 0 ? 0 :
-                    Frame.X + offset + Frame.Width > barSize ? Math.Max (barSize - Frame.Width, 0) : Frame.X + offset;
+                X = Frame.X + offset < 0
+                        ? 0
+                        : Frame.X + offset + Frame.Width > barSize
+                            ? Math.Max (barSize - Frame.Width, 0)
+                            : Frame.X + offset;
 
                 SuperViewAsScroll.Position = GetPositionFromSliderLocation (Frame.X);
             }
@@ -119,7 +120,9 @@ internal class ScrollSlider : View
         else if ((mouseEvent.Flags == MouseFlags.WheeledDown && SuperViewAsScroll.Orientation == Orientation.Vertical)
                  || (mouseEvent.Flags == MouseFlags.WheeledRight && SuperViewAsScroll.Orientation == Orientation.Horizontal))
         {
-            SuperViewAsScroll.Position = Math.Min (SuperViewAsScroll.Position + 1, SuperViewAsScroll.Size - barSize);
+            SuperViewAsScroll.Position = Math.Min (
+                                                   SuperViewAsScroll.Position + 1,
+                                                   SuperViewAsScroll.KeepContentInAllViewport ? SuperViewAsScroll.Size - barSize : SuperViewAsScroll.Size - 1);
         }
         else if ((mouseEvent.Flags == MouseFlags.WheeledUp && SuperViewAsScroll.Orientation == Orientation.Vertical)
                  || (mouseEvent.Flags == MouseFlags.WheeledLeft && SuperViewAsScroll.Orientation == Orientation.Horizontal))
@@ -162,10 +165,17 @@ internal class ScrollSlider : View
         if ((SuperViewAsScroll.Orientation == Orientation.Vertical && location + Frame.Height >= scrollSize)
             || (SuperViewAsScroll.Orientation == Orientation.Horizontal && location + Frame.Width >= scrollSize))
         {
-            return SuperViewAsScroll.Size - scrollSize + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize);
+            return Math.Min (
+                             Math.Max (SuperViewAsScroll.Position + location, 0),
+                             SuperViewAsScroll.KeepContentInAllViewport ? SuperViewAsScroll.Size - scrollSize : SuperViewAsScroll.Size - 1);
         }
 
-        return (int)Math.Min (Math.Round ((double)(location * SuperViewAsScroll.Size + location) / scrollSize), SuperViewAsScroll.Size - scrollSize);
+        return (int)Math.Min (
+                              Math.Round (
+                                          (double)(location * (SuperViewAsScroll.Size + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize))
+                                                   + location)
+                                          / scrollSize),
+                              SuperViewAsScroll.Size - scrollSize + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize));
     }
 
     internal (int Location, int Dimension) GetSliderLocationDimensionFromPosition ()
@@ -183,18 +193,31 @@ internal class ScrollSlider : View
 
         if (SuperViewAsScroll.Size > 0)
         {
-            dimension = (int)Math.Min (Math.Max (Math.Ceiling ((double)scrollSize * scrollSize / SuperViewAsScroll.Size), 1), scrollSize);
+            dimension = (int)Math.Min (
+                                       Math.Max (
+                                                 Math.Ceiling (
+                                                               (double)scrollSize
+                                                               * scrollSize
+                                                               / (SuperViewAsScroll.Size + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize))),
+                                                 1),
+                                       scrollSize);
 
             // Ensure the Position is valid
             if (SuperViewAsScroll.Position > 0
                 && SuperViewAsScroll.Position + scrollSize > SuperViewAsScroll.Size + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize))
             {
-                SuperViewAsScroll.Position = SuperViewAsScroll.Size - scrollSize;
+                SuperViewAsScroll.Position = SuperViewAsScroll.KeepContentInAllViewport ? SuperViewAsScroll.Size - scrollSize : SuperViewAsScroll.Size - 1;
             }
 
-            location = (int)Math.Min (Math.Round ((double)SuperViewAsScroll.Position * scrollSize / (SuperViewAsScroll.Size + 1)), scrollSize - dimension);
+            location = (int)Math.Min (
+                                      Math.Round (
+                                                  (double)SuperViewAsScroll.Position
+                                                  * scrollSize
+                                                  / (SuperViewAsScroll.Size + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize))),
+                                      scrollSize - dimension);
 
-            if (SuperViewAsScroll.Position == SuperViewAsScroll.Size - scrollSize && location + dimension < scrollSize)
+            if (SuperViewAsScroll.Position == SuperViewAsScroll.Size - scrollSize + (SuperViewAsScroll.KeepContentInAllViewport ? 0 : scrollSize)
+                && location + dimension < scrollSize)
             {
                 location = scrollSize - dimension;
             }

+ 58 - 8
UICatalog/Scenarios/ContentScrolling.cs

@@ -123,11 +123,12 @@ public class ContentScrolling : Scenario
             Width = Dim.Fill (),
             Height = Dim.Fill ()
         };
+
         app.Add (view);
 
         // Add Scroll Setting UI to Padding
-        view.Padding.Thickness = new (0, 3, 0, 0);
-        view.Padding.ColorScheme = Colors.ColorSchemes ["Error"];
+        view.Padding.Thickness = view.Padding.Thickness with { Top = view.Padding.Thickness.Top + 4 };
+        //view.Padding.ColorScheme = Colors.ColorSchemes ["Error"];
 
         var cbAllowNegativeX = new CheckBox
         {
@@ -135,7 +136,7 @@ public class ContentScrolling : Scenario
             Y = 0,
             CanFocus = false
         };
-        cbAllowNegativeX.CheckedState = view.ViewportSettings.HasFlag(ViewportSettings.AllowNegativeX) ? CheckState.Checked : CheckState.UnChecked;
+        cbAllowNegativeX.CheckedState = view.ViewportSettings.HasFlag (ViewportSettings.AllowNegativeX) ? CheckState.Checked : CheckState.UnChecked;
         cbAllowNegativeX.CheckedStateChanging += AllowNegativeX_Toggle;
 
         void AllowNegativeX_Toggle (object sender, CancelEventArgs<CheckState> e)
@@ -159,7 +160,7 @@ public class ContentScrolling : Scenario
             Y = 0,
             CanFocus = false
         };
-        cbAllowNegativeY.CheckedState = view.ViewportSettings.HasFlag(ViewportSettings.AllowNegativeY) ? CheckState.Checked : CheckState.UnChecked;
+        cbAllowNegativeY.CheckedState = view.ViewportSettings.HasFlag (ViewportSettings.AllowNegativeY) ? CheckState.Checked : CheckState.UnChecked;
         cbAllowNegativeY.CheckedStateChanging += AllowNegativeY_Toggle;
 
         void AllowNegativeY_Toggle (object sender, CancelEventArgs<CheckState> e)
@@ -182,7 +183,7 @@ public class ContentScrolling : Scenario
             Y = Pos.Bottom (cbAllowNegativeX),
             CanFocus = false
         };
-        cbAllowXGreaterThanContentWidth.CheckedState = view.ViewportSettings.HasFlag(ViewportSettings.AllowXGreaterThanContentWidth) ? CheckState.Checked : CheckState.UnChecked;
+        cbAllowXGreaterThanContentWidth.CheckedState = view.ViewportSettings.HasFlag (ViewportSettings.AllowXGreaterThanContentWidth) ? CheckState.Checked : CheckState.UnChecked;
         cbAllowXGreaterThanContentWidth.CheckedStateChanging += AllowXGreaterThanContentWidth_Toggle;
 
         void AllowXGreaterThanContentWidth_Toggle (object sender, CancelEventArgs<CheckState> e)
@@ -206,7 +207,7 @@ public class ContentScrolling : Scenario
             Y = Pos.Bottom (cbAllowNegativeX),
             CanFocus = false
         };
-        cbAllowYGreaterThanContentHeight.CheckedState = view.ViewportSettings.HasFlag(ViewportSettings.AllowYGreaterThanContentHeight) ? CheckState.Checked : CheckState.UnChecked;
+        cbAllowYGreaterThanContentHeight.CheckedState = view.ViewportSettings.HasFlag (ViewportSettings.AllowYGreaterThanContentHeight) ? CheckState.Checked : CheckState.UnChecked;
         cbAllowYGreaterThanContentHeight.CheckedStateChanging += AllowYGreaterThanContentHeight_Toggle;
 
         void AllowYGreaterThanContentHeight_Toggle (object sender, CancelEventArgs<CheckState> e)
@@ -284,7 +285,7 @@ public class ContentScrolling : Scenario
             Y = Pos.Top (labelContentSize),
             CanFocus = false
         };
-        cbClearOnlyVisible.CheckedState = view.ViewportSettings.HasFlag(ViewportSettings.ClearContentOnly) ? CheckState.Checked : CheckState.UnChecked;
+        cbClearOnlyVisible.CheckedState = view.ViewportSettings.HasFlag (ViewportSettings.ClearContentOnly) ? CheckState.Checked : CheckState.UnChecked;
         cbClearOnlyVisible.CheckedStateChanging += ClearVisibleContentOnly_Toggle;
 
         void ClearVisibleContentOnly_Toggle (object sender, CancelEventArgs<CheckState> e)
@@ -321,7 +322,56 @@ public class ContentScrolling : Scenario
             }
         }
 
-        view.Padding.Add (labelContentSize, contentSizeWidth, labelComma, contentSizeHeight, cbClearOnlyVisible, cbDoNotClipContent);
+        var cbVerticalScrollBar = new CheckBox
+        {
+            Title = "Vertical ScrollBar",
+            X = 0,
+            Y = Pos.Bottom (labelContentSize),
+            CanFocus = false
+        };
+        view.VerticalScrollBar.ShowScrollIndicator = false;
+        cbVerticalScrollBar.CheckedState = view.VerticalScrollBar.Visible ? CheckState.Checked : CheckState.UnChecked;
+        cbVerticalScrollBar.CheckedStateChanging += VerticalScrollBar_Toggle;
+
+        void VerticalScrollBar_Toggle (object sender, CancelEventArgs<CheckState> e)
+        {
+            view.VerticalScrollBar.ShowScrollIndicator = e.NewValue == CheckState.Checked;
+        }
+
+        var cbHorizontalScrollBar = new CheckBox
+        {
+            Title = "Horizontal ScrollBar",
+            X = Pos.Right (cbVerticalScrollBar) + 1,
+            Y = Pos.Bottom (labelContentSize),
+            CanFocus = false
+        };
+        view.HorizontalScrollBar.ShowScrollIndicator = false;
+        cbHorizontalScrollBar.CheckedState = view.HorizontalScrollBar.ShowScrollIndicator ? CheckState.Checked : CheckState.UnChecked;
+        cbHorizontalScrollBar.CheckedStateChanging += HorizontalScrollBar_Toggle;
+
+        void HorizontalScrollBar_Toggle (object sender, CancelEventArgs<CheckState> e)
+        {
+            view.HorizontalScrollBar.ShowScrollIndicator = e.NewValue == CheckState.Checked;
+        }
+
+        var cbAutoHideScrollBars = new CheckBox
+        {
+            Title = "Auto-hide ScrollBars",
+            X = Pos.Right (cbHorizontalScrollBar) + 1,
+            Y = Pos.Bottom (labelContentSize),
+            CanFocus = false
+        };
+        view.HorizontalScrollBar.AutoHide = true;
+        view.VerticalScrollBar.AutoHide = true;
+        cbAutoHideScrollBars.CheckedState = view.HorizontalScrollBar.AutoHide ? CheckState.Checked : CheckState.UnChecked;
+        cbAutoHideScrollBars.CheckedStateChanging += AutoHideScrollBars_Toggle;
+
+        void AutoHideScrollBars_Toggle (object sender, CancelEventArgs<CheckState> e)
+        {
+            view.HorizontalScrollBar.AutoHide = view.VerticalScrollBar.AutoHide = e.NewValue == CheckState.Checked;
+        }
+
+        view.Padding.Add (labelContentSize, contentSizeWidth, labelComma, contentSizeHeight, cbClearOnlyVisible, cbDoNotClipContent, cbVerticalScrollBar, cbHorizontalScrollBar, cbAutoHideScrollBars);
 
         // Add demo views to show that things work correctly
         var textField = new TextField { X = 20, Y = 7, Width = 15, Text = "Test TextField" };

+ 11 - 9
UnitTests/Views/ScrollBarTests.cs

@@ -245,7 +245,8 @@ public class ScrollBarTests
         top.Add (view);
         Application.Begin (top);
 
-        Assert.True (scrollBar.KeepContentInAllViewport);
+        Assert.False (scrollBar.KeepContentInAllViewport);
+        scrollBar.KeepContentInAllViewport = true;
         Assert.Equal (80, view.Padding.Viewport.Width);
         Assert.Equal (25, view.Padding.Viewport.Height);
         Assert.Equal (2, scrollBar.Viewport.Width);
@@ -705,7 +706,7 @@ public class ScrollBarTests
                     20,
                     @"
 ◄░░░░██░░►")]
-    public void Mouse_On_The_Slider (
+    public void Mouse_On_The_Slider_KeepContentInAllViewport_True (
         Orientation orientation,
         int size,
         int position,
@@ -722,7 +723,8 @@ public class ScrollBarTests
             Width = orientation == Orientation.Vertical ? 1 : 10,
             Height = orientation == Orientation.Vertical ? 10 : 1,
             Orientation = orientation,
-            Size = size, Position = position
+            Size = size, Position = position,
+            KeepContentInAllViewport = true
         };
         var top = new Toplevel ();
         top.Add (scrollBar);
@@ -782,12 +784,12 @@ public class ScrollBarTests
     [AutoInitShutdown]
     [InlineData (Orientation.Vertical)]
     [InlineData (Orientation.Horizontal)]
-    public void Mouse_Pressed_On_ScrollButton_Changes_Position (Orientation orientation)
+    public void Mouse_Pressed_On_ScrollButton_Changes_Position_KeepContentInAllViewport_True (Orientation orientation)
     {
         var scrollBar = new ScrollBar
         {
             X = 10, Y = 10, Width = orientation == Orientation.Vertical ? 1 : 10, Height = orientation == Orientation.Vertical ? 10 : 1, Size = 20,
-            Orientation = orientation
+            Orientation = orientation, KeepContentInAllViewport = true
         };
         var top = new Toplevel ();
         top.Add (scrollBar);
@@ -881,9 +883,9 @@ public class ScrollBarTests
     [Theory]
     [InlineData (Orientation.Vertical, 20, 12, 10)]
     [InlineData (Orientation.Vertical, 40, 32, 30)]
-    public void Position_Cannot_Be_Negative_Nor_Greater_Than_Size_Minus_Frame_Length (Orientation orientation, int size, int expectedPos1, int expectedPos2)
+    public void Position_Cannot_Be_Negative_Nor_Greater_Than_Size_Minus_Frame_Length_KeepContentInAllViewport_True (Orientation orientation, int size, int expectedPos1, int expectedPos2)
     {
-        var scrollBar = new ScrollBar { Orientation = orientation, Height = 10, Size = size };
+        var scrollBar = new ScrollBar { Orientation = orientation, Height = 10, Size = size, KeepContentInAllViewport = true };
         Assert.Equal (0, scrollBar.Position);
 
         scrollBar.Position = -1;
@@ -926,12 +928,12 @@ public class ScrollBarTests
     }
 
     [Fact]
-    public void PositionChanging_PositionChanged_Events_Only_Raises_Once_If_Position_Was_Really_Changed ()
+    public void PositionChanging_PositionChanged_Events_Only_Raises_Once_If_Position_Was_Really_Changed_KeepContentInAllViewport_True ()
     {
         var changing = 0;
         var cancel = false;
         var changed = 0;
-        var scrollBar = new ScrollBar { Height = 10, Size = 20 };
+        var scrollBar = new ScrollBar { Height = 10, Size = 20, KeepContentInAllViewport = true };
         scrollBar.PositionChanging += Scroll_PositionChanging;
         scrollBar.PositionChanged += Scroll_PositionChanged;
 

+ 3 - 2
UnitTests/Views/ScrollSliderTests.cs

@@ -14,7 +14,7 @@ public class ScrollSliderTests
     [InlineData (Orientation.Vertical, 26, 236, 27, 210)]
     [InlineData (Orientation.Vertical, 37, 236, 2, 13)]
     [InlineData (Orientation.Vertical, 42, 236, 29, 164)]
-    public void Test_Position_Location_Consistency (Orientation orientation, int scrollLength, int size, int location, int expectedPosition)
+    public void Test_Position_Location_Consistency_KeepContentInAllViewport_True (Orientation orientation, int scrollLength, int size, int location, int expectedPosition)
     {
         // Arrange
         Scroll scroll = new ()
@@ -22,7 +22,8 @@ public class ScrollSliderTests
             Orientation = orientation,
             Width = orientation == Orientation.Vertical ? 1 : scrollLength,
             Height = orientation == Orientation.Vertical ? scrollLength : 1,
-            Size = size
+            Size = size,
+            KeepContentInAllViewport = true
         };
 
         scroll.BeginInit ();

+ 10 - 9
UnitTests/Views/ScrollTests.cs

@@ -190,17 +190,17 @@ public class ScrollTests
         Assert.Equal (Orientation.Vertical, scroll.Orientation);
         Assert.Equal (0, scroll.Size);
         Assert.Equal (0, scroll.Position);
-        Assert.True (scroll.KeepContentInAllViewport);
+        Assert.False (scroll.KeepContentInAllViewport);
     }
 
     [Fact]
     [AutoInitShutdown]
-    public void KeepContentInAllViewport_True_False ()
+    public void KeepContentInAllViewport_True_False_KeepContentInAllViewport_True ()
     {
         var view = new View { Width = Dim.Fill (), Height = Dim.Fill () };
         view.Padding.Thickness = new (0, 0, 2, 0);
         view.SetContentSize (new (view.Viewport.Width, 30));
-        var scroll = new Scroll { Width = 2, Height = Dim.Fill (), Size = view.GetContentSize ().Height };
+        var scroll = new Scroll { Width = 2, Height = Dim.Fill (), Size = view.GetContentSize ().Height, KeepContentInAllViewport = true };
         scroll.PositionChanged += (_, e) => view.Viewport = view.Viewport with { Y = e.CurrentValue };
         view.Padding.Add (scroll);
         var top = new Toplevel ();
@@ -667,7 +667,7 @@ public class ScrollTests
                     16,
                     @"
 ░░░░███░░░")]
-    public void Mouse_On_The_Slider (
+    public void Mouse_On_The_Slider_KeepContentInAllViewport_True (
         Orientation orientation,
         int size,
         int position,
@@ -684,7 +684,8 @@ public class ScrollTests
             Width = orientation == Orientation.Vertical ? 1 : 10,
             Height = orientation == Orientation.Vertical ? 10 : 1,
             Orientation = orientation,
-            Size = size, Position = position
+            Size = size, Position = position,
+            KeepContentInAllViewport = true
         };
         var top = new Toplevel ();
         top.Add (scroll);
@@ -782,9 +783,9 @@ public class ScrollTests
     [Theory]
     [InlineData (Orientation.Vertical, 20, 10)]
     [InlineData (Orientation.Vertical, 40, 30)]
-    public void Position_Cannot_Be_Negative_Nor_Greater_Than_Size_Minus_Frame_Length (Orientation orientation, int size, int expectedPos)
+    public void Position_Cannot_Be_Negative_Nor_Greater_Than_Size_Minus_Frame_Length_KeepContentInAllViewport_True (Orientation orientation, int size, int expectedPos)
     {
-        var scroll = new Scroll { Orientation = orientation, Height = 10, Size = size };
+        var scroll = new Scroll { Orientation = orientation, Height = 10, Size = size, KeepContentInAllViewport = true };
         Assert.Equal (0, scroll.Position);
 
         scroll.Position = -1;
@@ -827,12 +828,12 @@ public class ScrollTests
     }
 
     [Fact]
-    public void PositionChanging_PositionChanged_Events_Only_Raises_Once_If_Position_Was_Really_Changed ()
+    public void PositionChanging_PositionChanged_Events_Only_Raises_Once_If_Position_Was_Really_Changed_KeepContentInAllViewport_True ()
     {
         var changing = 0;
         var cancel = false;
         var changed = 0;
-        var scroll = new Scroll { Height = 10, Size = 20 };
+        var scroll = new Scroll { Height = 10, Size = 20, KeepContentInAllViewport = true };
         scroll.PositionChanging += Scroll_PositionChanging;
         scroll.PositionChanged += Scroll_PositionChanged;