2
0
Эх сурвалжийг харах

Merge branch 'gui-cs:v2_develop' into v2_develop

Tig 1 долоо хоног өмнө
parent
commit
2ca3006746
55 өөрчлөгдсөн 431 нэмэгдсэн , 247 устгасан
  1. 1 1
      Examples/UICatalog/Scenarios/Adornments.cs
  2. 4 4
      Examples/UICatalog/Scenarios/AllViewsTester.cs
  3. 1 1
      Examples/UICatalog/Scenarios/Arrangement.cs
  4. 2 1
      Examples/UICatalog/Scenarios/CharacterMap/CharacterMap.cs
  5. 1 1
      Examples/UICatalog/Scenarios/ConfigurationEditor.cs
  6. 1 1
      Examples/UICatalog/Scenarios/DynamicMenuBar.cs
  7. 1 1
      Examples/UICatalog/Scenarios/EditorsAndHelpers/AdornmentEditor.cs
  8. 1 1
      Examples/UICatalog/Scenarios/EditorsAndHelpers/AdornmentsEditor.cs
  9. 3 3
      Examples/UICatalog/Scenarios/EditorsAndHelpers/DimEditor.cs
  10. 1 1
      Examples/UICatalog/Scenarios/EditorsAndHelpers/EventLog.cs
  11. 3 3
      Examples/UICatalog/Scenarios/EditorsAndHelpers/PosEditor.cs
  12. 1 1
      Examples/UICatalog/Scenarios/ListColumns.cs
  13. 1 1
      Examples/UICatalog/Scenarios/ListViewWithSelection.cs
  14. 1 1
      Examples/UICatalog/Scenarios/Mouse.cs
  15. 8 8
      Examples/UICatalog/Scenarios/ScrollBarDemo.cs
  16. 7 7
      Examples/UICatalog/Scenarios/Shortcuts.cs
  17. 1 1
      Examples/UICatalog/Scenarios/SingleBackgroundWorker.cs
  18. 3 3
      Examples/UICatalog/Scenarios/ViewportSettings.cs
  19. 5 5
      Examples/UICatalog/Scenarios/Wizards.cs
  20. 4 29
      Examples/UICatalog/UICatalogTop.cs
  21. 3 4
      Terminal.Gui/App/Application.Run.cs
  22. 9 3
      Terminal.Gui/Drivers/AnsiResponseParser/Keyboard/CsiCursorPattern.cs
  23. 5 3
      Terminal.Gui/ViewBase/Layout/Dim.cs
  24. 2 2
      Terminal.Gui/ViewBase/Layout/DimAuto.cs
  25. 13 6
      Terminal.Gui/ViewBase/Layout/DimFunc.cs
  26. 5 3
      Terminal.Gui/ViewBase/Layout/Pos.cs
  27. 1 1
      Terminal.Gui/ViewBase/Layout/PosAlign.cs
  28. 19 4
      Terminal.Gui/ViewBase/Layout/PosFunc.cs
  29. 32 11
      Terminal.Gui/ViewBase/View.Drawing.cs
  30. 9 4
      Terminal.Gui/ViewBase/View.Layout.cs
  31. 2 2
      Terminal.Gui/ViewBase/View.ScrollBars.cs
  32. 20 0
      Terminal.Gui/ViewBase/ViewCollectionHelpers.cs
  33. 2 2
      Terminal.Gui/Views/FileDialogs/FileDialog.cs
  34. 2 2
      Terminal.Gui/Views/Menu/Menuv2.cs
  35. 1 1
      Terminal.Gui/Views/Menuv1/Menu.cs
  36. 4 4
      Terminal.Gui/Views/MessageBox.cs
  37. 1 1
      Terminal.Gui/Views/NumericUpDown.cs
  38. 2 2
      Terminal.Gui/Views/ScrollBar/ScrollBar.cs
  39. 4 4
      Terminal.Gui/Views/Shortcut.cs
  40. 4 4
      Terminal.Gui/Views/Wizard/Wizard.cs
  41. 78 58
      Tests/TerminalGuiFluentTesting/GuiTestContext.cs
  42. 1 2
      Tests/UnitTests/ConsoleDrivers/AnsiKeyboardParserTests.cs
  43. 0 1
      Tests/UnitTests/View/Draw/ClearViewportTests.cs
  44. 1 1
      Tests/UnitTests/Views/LabelTests.cs
  45. 9 1
      Tests/UnitTests/Views/TileViewTests.cs
  46. 33 17
      Tests/UnitTestsParallelizable/View/Draw/NeedsDrawTests.cs
  47. 1 1
      Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.DimTypes.cs
  48. 2 1
      Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.PosTypes.cs
  49. 2 2
      Tests/UnitTestsParallelizable/View/Layout/Dim.FillTests.cs
  50. 48 5
      Tests/UnitTestsParallelizable/View/Layout/Dim.FuncTests.cs
  51. 8 8
      Tests/UnitTestsParallelizable/View/Layout/FrameTests.cs
  52. 49 5
      Tests/UnitTestsParallelizable/View/Layout/Pos.FuncTests.cs
  53. 2 2
      Tests/UnitTestsParallelizable/View/Layout/Pos.Tests.cs
  54. 4 4
      Tests/UnitTestsParallelizable/View/Layout/SetLayoutTests.cs
  55. 3 2
      Tests/UnitTestsParallelizable/View/Layout/SetRelativeLayoutTests.cs

+ 1 - 1
Examples/UICatalog/Scenarios/Adornments.cs

@@ -35,7 +35,7 @@ public class Adornments : Scenario
             Title = "The _Window",
             Arrangement = ViewArrangement.Overlapped | ViewArrangement.Movable,
 
-            Width = Dim.Fill (Dim.Func (() => editor.Frame.Width)),
+            Width = Dim.Fill (Dim.Func (_ => editor.Frame.Width)),
             Height = Dim.Fill ()
         };
         app.Add (window);

+ 4 - 4
Examples/UICatalog/Scenarios/AllViewsTester.cs

@@ -101,7 +101,7 @@ public class AllViewsTester : Scenario
         {
             Title = "Arrangement [_3]",
             X = Pos.Right (_classListView) - 1,
-            Y = Pos.Bottom (_adornmentsEditor) - Pos.Func (() => _adornmentsEditor.Frame.Height == 1 ? 0 : 1),
+            Y = Pos.Bottom (_adornmentsEditor) - Pos.Func (_ => _adornmentsEditor.Frame.Height == 1 ? 0 : 1),
             Width = Dim.Width (_adornmentsEditor),
             Height = Dim.Fill (),
             AutoSelectViewToEdit = false,
@@ -134,7 +134,7 @@ public class AllViewsTester : Scenario
         {
             Title = "ViewportSettings [_5]",
             X = Pos.Right (_arrangementEditor) - 1,
-            Y = Pos.Bottom (_layoutEditor) - Pos.Func (() => _layoutEditor.Frame.Height == 1 ? 0 : 1),
+            Y = Pos.Bottom (_layoutEditor) - Pos.Func (_ => _layoutEditor.Frame.Height == 1 ? 0 : 1),
             Width = Dim.Width (_layoutEditor),
             Height = Dim.Auto (),
             CanFocus = true,
@@ -148,7 +148,7 @@ public class AllViewsTester : Scenario
         {
             Title = "View Properties [_6]",
             X = Pos.Right (_adornmentsEditor) - 1,
-            Y = Pos.Bottom (_viewportSettingsEditor) - Pos.Func (() => _viewportSettingsEditor.Frame.Height == 1 ? 0 : 1),
+            Y = Pos.Bottom (_viewportSettingsEditor) - Pos.Func (_ => _viewportSettingsEditor.Frame.Height == 1 ? 0 : 1),
             Width = Dim.Width (_layoutEditor),
             Height = Dim.Auto (),
             CanFocus = true,
@@ -171,7 +171,7 @@ public class AllViewsTester : Scenario
 
         _layoutEditor.Width = Dim.Fill (
                                         Dim.Func (
-                                                  () =>
+                                                  _ =>
                                                   {
                                                       if (_eventLog.NeedsLayout)
                                                       {

+ 1 - 1
Examples/UICatalog/Scenarios/Arrangement.cs

@@ -66,7 +66,7 @@ public class Arrangement : Scenario
         View tiledView3 = CreateTiledView (2, Pos.Right (tiledView2) - 1, Pos.Top (tiledView2));
         tiledView3.Height = Dim.Height (tiledView1);
         View tiledView4 = CreateTiledView (3, Pos.Left (tiledView1), Pos.Bottom (tiledView1) - 1);
-        tiledView4.Width = Dim.Func (() => tiledView3.Frame.Width + tiledView2.Frame.Width + tiledView1.Frame.Width - 2);
+        tiledView4.Width = Dim.Func (_ => tiledView3.Frame.Width + tiledView2.Frame.Width + tiledView1.Frame.Width - 2);
 
         View movableSizeableWithProgress = CreateOverlappedView (2, 10, 8);
         movableSizeableWithProgress.Title = "Movable _& Sizable";

+ 2 - 1
Examples/UICatalog/Scenarios/CharacterMap/CharacterMap.cs

@@ -39,7 +39,6 @@ public class CharacterMap : Scenario
         {
             X = 0,
             Y = 1,
-            Width = Dim.Fill (Dim.Func (() => _categoryList!.Frame.Width)),
             Height = Dim.Fill (),
            // SchemeName = "Base"
 
@@ -172,6 +171,8 @@ public class CharacterMap : Scenario
         };
         top.Add (menu);
 
+        _charMap.Width = Dim.Fill (Dim.Func (v => v!.Frame.Width, _categoryList));
+
         _charMap.SelectedCodePoint = 0;
         _charMap.SetFocus ();
 

+ 1 - 1
Examples/UICatalog/Scenarios/ConfigurationEditor.cs

@@ -55,7 +55,7 @@ public class ConfigurationEditor : Scenario
         _tabView = new ()
         {
             Width = Dim.Fill (),
-            Height = Dim.Fill (Dim.Func (() => statusBar.Frame.Height))
+            Height = Dim.Fill (Dim.Func (_ => statusBar.Frame.Height))
         };
 
         win.Add (_tabView, statusBar);

+ 1 - 1
Examples/UICatalog/Scenarios/DynamicMenuBar.cs

@@ -598,7 +598,7 @@ public class DynamicMenuBar : Scenario
                 X = Pos.Right (btnPrevious) + 1,
                 Y = Pos.Top (btnPrevious),
 
-                Width = Dim.Fill () - Dim.Func (() => btnAdd.Frame.Width + 1),
+                Width = Dim.Fill () - Dim.Func (_ => btnAdd.Frame.Width + 1),
                 Height = 1
             };
 

+ 1 - 1
Examples/UICatalog/Scenarios/EditorsAndHelpers/AdornmentEditor.cs

@@ -100,7 +100,7 @@ public class AdornmentEditor : EditorBase
 
         _leftEdit = new ()
         {
-            X = Pos.Left (_topEdit) - Pos.Func (() => _topEdit.Text.Length) - 2, Y = Pos.Bottom (_topEdit),
+            X = Pos.Left (_topEdit) - Pos.Func (_ => _topEdit.Text.Length) - 2, Y = Pos.Bottom (_topEdit),
             Format = _topEdit.Format
         };
 

+ 1 - 1
Examples/UICatalog/Scenarios/EditorsAndHelpers/AdornmentsEditor.cs

@@ -122,7 +122,7 @@ public class AdornmentsEditor : EditorBase
         PaddingEditor.Border!.Thickness = PaddingEditor.Border.Thickness with { Bottom = 0 };
         Add (PaddingEditor);
 
-        Width = Dim.Auto (maximumContentDim: Dim.Func (() => MarginEditor.Frame.Width - 2));
+        Width = Dim.Auto (maximumContentDim: Dim.Func (_ => MarginEditor.Frame.Width - 2));
 
         MarginEditor.ExpanderButton!.Collapsed = true;
         BorderEditor.ExpanderButton!.Collapsed = true;

+ 3 - 3
Examples/UICatalog/Scenarios/EditorsAndHelpers/DimEditor.cs

@@ -68,7 +68,7 @@ public class DimEditor : EditorBase
                 break;
             case DimFunc func:
                 _valueEdit.Enabled = true;
-                _value = func.Fn ();
+                _value = func.Fn (null);
                 _valueEdit!.Text = _value.ToString ();
                 break;
             case DimPercent percent:
@@ -98,7 +98,7 @@ public class DimEditor : EditorBase
         {
             X = Pos.Right (label) + 1,
             Y = 0,
-            Width = Dim.Func (() => _radioItems.Max (i => i.GetColumns ()) - label.Frame.Width + 1),
+            Width = Dim.Func (_ => _radioItems.Max (i => i.GetColumns ()) - label.Frame.Width + 1),
             Text = $"{_value}"
         };
 
@@ -141,7 +141,7 @@ public class DimEditor : EditorBase
                 0 => Dim.Absolute (_value),
                 1 => Dim.Auto (),
                 2 => Dim.Fill (_value),
-                3 => Dim.Func (() => _value),
+                3 => Dim.Func (_ => _value),
                 4 => Dim.Percent (_value),
                 _ => Dimension == Dimension.Width ? ViewToEdit.Width : ViewToEdit.Height
             };

+ 1 - 1
Examples/UICatalog/Scenarios/EditorsAndHelpers/EventLog.cs

@@ -20,7 +20,7 @@ public class EventLog : ListView
         Y = 0;
 
         Width = Dim.Func (
-                          () =>
+                          _ =>
                           {
                               if (!IsInitialized)
                               {

+ 3 - 3
Examples/UICatalog/Scenarios/EditorsAndHelpers/PosEditor.cs

@@ -70,7 +70,7 @@ public class PosEditor : EditorBase
                 break;
             case PosFunc func:
                 _valueEdit.Enabled = true;
-                _value = func.Fn ();
+                _value = func.Fn (null);
                 _valueEdit!.Text = _value.ToString ();
 
                 break;
@@ -98,7 +98,7 @@ public class PosEditor : EditorBase
         {
             X = Pos.Right (label) + 1,
             Y = 0,
-            Width = Dim.Func (() => _radioItems.Max (i => i.GetColumns ()) - label.Frame.Width + 1),
+            Width = Dim.Func (_ => _radioItems.Max (i => i.GetColumns ()) - label.Frame.Width + 1),
             Text = $"{_value}"
         };
 
@@ -142,7 +142,7 @@ public class PosEditor : EditorBase
                            1 => Pos.Align (Alignment.Start),
                            2 => new PosAnchorEnd (),
                            3 => Pos.Center (),
-                           4 => Pos.Func (() => _value),
+                           4 => Pos.Func (_ => _value),
                            5 => Pos.Percent (_value),
                            _ => Dimension == Dimension.Width ? ViewToEdit.X : ViewToEdit.Y
                        };

+ 1 - 1
Examples/UICatalog/Scenarios/ListColumns.cs

@@ -252,7 +252,7 @@ public class ListColumns : Scenario
 
         top.Add (menu, appWindow, statusBar);
         appWindow.Y = 1;
-        appWindow.Height = Dim.Fill(Dim.Func (() => statusBar.Frame.Height));
+        appWindow.Height = Dim.Fill(Dim.Func (_ => statusBar.Frame.Height));
 
         // Run - Start the application.
         Application.Run (top);

+ 1 - 1
Examples/UICatalog/Scenarios/ListViewWithSelection.cs

@@ -76,7 +76,7 @@ public class ListViewWithSelection : Scenario
             Title = "_ListView",
             X = 0,
             Y = Pos.Bottom (_allowMarkingCb),
-            Width = Dim.Func (() => _listView?.MaxLength ?? 10),
+            Width = Dim.Func (_ => _listView?.MaxLength ?? 10),
             Height = Dim.Fill (),
             AllowsMarking = false,
             AllowsMultipleSelection = false,

+ 1 - 1
Examples/UICatalog/Scenarios/Mouse.cs

@@ -109,7 +109,7 @@ public class Mouse : Scenario
                                    X = 0,
                                    Y = 0,
                                    Width = Dim.Fill (),
-                                   Height = Dim.Func (() => demo.Padding.Thickness.Top),
+                                   Height = Dim.Func (_ => demo.Padding.Thickness.Top),
                                    Title = "inPadding",
                                    Id = "inPadding"
                                });

+ 8 - 8
Examples/UICatalog/Scenarios/ScrollBarDemo.cs

@@ -72,7 +72,7 @@ public class ScrollBarDemo : Scenario
             Text = "_Width/Height:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, AlignmentModes.StartToEnd, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblWidthHeight);
 
@@ -114,7 +114,7 @@ public class ScrollBarDemo : Scenario
             Text = "_Orientation:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblOrientationLabel);
 
@@ -160,7 +160,7 @@ public class ScrollBarDemo : Scenario
             Text = "Scrollable_ContentSize:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblSize);
 
@@ -193,7 +193,7 @@ public class ScrollBarDemo : Scenario
             Text = "_VisibleContentSize:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblVisibleContentSize);
 
@@ -226,7 +226,7 @@ public class ScrollBarDemo : Scenario
             Text = "_Position:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
 
         };
         demoFrame.Add (lblPosition);
@@ -264,7 +264,7 @@ public class ScrollBarDemo : Scenario
             Text = "Options:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblOptions);
         var autoShow = new CheckBox
@@ -282,7 +282,7 @@ public class ScrollBarDemo : Scenario
             Text = "SliderPosition:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
         };
         demoFrame.Add (lblSliderPosition);
 
@@ -299,7 +299,7 @@ public class ScrollBarDemo : Scenario
             Text = "Scrolled:",
             TextAlignment = Alignment.End,
             Y = Pos.Align (Alignment.Start, groupId: 1),
-            Width = Dim.Func (() => GetMaxLabelWidth (1))
+            Width = Dim.Func (_ => GetMaxLabelWidth (1))
 
         };
         demoFrame.Add (lblScrolled);

+ 7 - 7
Examples/UICatalog/Scenarios/Shortcuts.cs

@@ -43,14 +43,14 @@ public class Shortcuts : Scenario
         };
 
         eventLog.Width = Dim.Func (
-                                   () => Math.Min (
-                                                   Application.Top.Viewport.Width / 2,
-                                                   eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
+                                   _ => Math.Min (
+                                                  Application.Top.Viewport.Width / 2,
+                                                  eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
 
         eventLog.Width = Dim.Func (
-                                   () => Math.Min (
-                                                   eventLog.SuperView!.Viewport.Width / 2,
-                                                   eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
+                                   _ => Math.Min (
+                                                  eventLog.SuperView!.Viewport.Width / 2,
+                                                  eventLog?.MaxLength + eventLog!.GetAdornmentsThickness ().Horizontal ?? 0));
         Application.Top.Add (eventLog);
 
         var alignKeysShortcut = new Shortcut
@@ -193,7 +193,7 @@ public class Shortcuts : Scenario
             Id = "appShortcut",
             X = 0,
             Y = Pos.Bottom (canFocusShortcut),
-            Width = Dim.Fill (Dim.Func (() => eventLog.Frame.Width)),
+            Width = Dim.Fill (Dim.Func (_ => eventLog.Frame.Width)),
             Title = "A_pp Shortcut",
             Key = Key.F1,
             Text = "Width is DimFill",

+ 1 - 1
Examples/UICatalog/Scenarios/SingleBackgroundWorker.cs

@@ -83,7 +83,7 @@ public class SingleBackgroundWorker : Scenario
             workerLogTop.Add (_listLog);
 
             workerLogTop.Y = 1;
-            workerLogTop.Height = Dim.Fill (Dim.Func (() => statusBar.Frame.Height));
+            workerLogTop.Height = Dim.Fill (Dim.Func (_ => statusBar.Frame.Height));
 
             Add (menu, workerLogTop, statusBar);
             Title = "MainApp";

+ 3 - 3
Examples/UICatalog/Scenarios/ViewportSettings.cs

@@ -124,8 +124,8 @@ public class ViewportSettings : Scenario
         var view = new ViewportSettingsDemoView
         {
             Title = "ViewportSettings Demo View",
-            Width = Dim.Fill (Dim.Func (() => app.IsInitialized ? adornmentsEditor.Frame.Width + 1 : 1)),
-            Height = Dim.Fill (Dim.Func (() => app.IsInitialized ? viewportSettingsEditor.Frame.Height : 1))
+            Width = Dim.Fill (Dim.Func (_ => app.IsInitialized ? adornmentsEditor.Frame.Width + 1 : 1)),
+            Height = Dim.Fill (Dim.Func (_ => app.IsInitialized ? viewportSettingsEditor.Frame.Height : 1))
         };
 
         app.Add (view);
@@ -164,7 +164,7 @@ public class ViewportSettings : Scenario
         {
             X = Pos.Center (),
             Y = Pos.Bottom (textView) + 1,
-            Width = Dim.Auto (DimAutoStyle.Content, maximumContentDim: Dim.Func (() => view.GetContentSize ().Width)),
+            Width = Dim.Auto (DimAutoStyle.Content, maximumContentDim: Dim.Func (_ => view.GetContentSize ().Width)),
             Height = Dim.Auto (DimAutoStyle.Content, maximumContentDim: Dim.Percent (20)),
         };
 

+ 5 - 5
Examples/UICatalog/Scenarios/Wizards.cs

@@ -282,11 +282,11 @@ public class Wizards : Scenario
 
                                            someText.Height = Dim.Fill (
                                                                        Dim.Func (
-                                                                                 () => someText.SuperView is { IsInitialized: true }
-                                                                                           ? someText.SuperView.SubViews
-                                                                                                     .First (view => view.Y.Has<PosAnchorEnd> (out _))
-                                                                                                     .Frame.Height
-                                                                                           : 1));
+                                                                                 v => someText.SuperView is { IsInitialized: true }
+                                                                                          ? someText.SuperView.SubViews
+                                                                                                    .First (view => view.Y.Has<PosAnchorEnd> (out _))
+                                                                                                    .Frame.Height
+                                                                                          : 1));
                                            var help = "This is helpful.";
                                            fourthStep.Add (someText);
 

+ 4 - 29
Examples/UICatalog/UICatalogTop.cs

@@ -404,20 +404,7 @@ public class UICatalogTop : Toplevel
             X = Pos.Right (_categoryList!) - 1,
             Y = Pos.Bottom (_menuBar!),
             Width = Dim.Fill (),
-            Height = Dim.Fill (
-                               Dim.Func (
-                                         () =>
-                                         {
-                                             if (_statusBar!.NeedsLayout)
-                                             {
-                                                 throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
-
-                                                 //_statusBar.Layout ();
-                                             }
-
-                                             return _statusBar.Frame.Height;
-                                         })),
-
+            Height = Dim.Fill (Dim.Func (v => v!.Frame.Height, _statusBar)),
             //AllowsMarking = false,
             CanFocus = true,
             Title = "_Scenarios",
@@ -515,19 +502,7 @@ public class UICatalogTop : Toplevel
             X = 0,
             Y = Pos.Bottom (_menuBar!),
             Width = Dim.Auto (),
-            Height = Dim.Fill (
-                               Dim.Func (
-                                         () =>
-                                         {
-                                             if (_statusBar!.NeedsLayout)
-                                             {
-                                                 throw new LayoutException ("DimFunc.Fn aborted because dependent View needs layout.");
-
-                                                 //_statusBar.Layout ();
-                                             }
-
-                                             return _statusBar.Frame.Height;
-                                         })),
+            Height = Dim.Fill (Dim.Func (v => v!.Frame.Height, _statusBar)),
             AllowsMarking = false,
             CanFocus = true,
             Title = "_Categories",
@@ -595,8 +570,8 @@ public class UICatalogTop : Toplevel
         // ReSharper disable All
         statusBar.Height = Dim.Auto (
                                      DimAutoStyle.Auto,
-                                     minimumContentDim: Dim.Func (() => statusBar.Visible ? 1 : 0),
-                                     maximumContentDim: Dim.Func (() => statusBar.Visible ? 1 : 0));
+                                     minimumContentDim: Dim.Func (_ => statusBar.Visible ? 1 : 0),
+                                     maximumContentDim: Dim.Func (_ => statusBar.Visible ? 1 : 0));
         // ReSharper restore All
 
         _shQuit = new ()

+ 3 - 4
Terminal.Gui/App/Application.Run.cs

@@ -205,6 +205,8 @@ public static partial class Application // Run (Begin, Run, End, Stop)
 
         toplevel.OnLoaded ();
 
+        LayoutAndDraw (true);
+
         if (PositionCursor ())
         {
             Driver?.UpdateCursor ();
@@ -212,9 +214,6 @@ public static partial class Application // Run (Begin, Run, End, Stop)
 
         NotifyNewRunState?.Invoke (toplevel, new (rs));
 
-        // Force an Idle event so that an Iteration (and Refresh) happen.
-        Invoke (() => { });
-
         return rs;
     }
 
@@ -535,7 +534,7 @@ public static partial class Application // Run (Begin, Run, End, Stop)
             return firstIteration;
         }
 
-        LayoutAndDraw ();
+        LayoutAndDraw (TopLevels.Any (v => v.NeedsLayout || v.NeedsDraw));
 
         if (PositionCursor ())
         {

+ 9 - 3
Terminal.Gui/Drivers/AnsiResponseParser/Keyboard/CsiCursorPattern.cs

@@ -7,11 +7,11 @@ namespace Terminal.Gui.Drivers;
 ///     Detects ansi escape sequences in strings that have been read from
 ///     the terminal (see <see cref="IAnsiResponseParser"/>).
 ///     Handles navigation CSI key parsing such as <c>\x1b[A</c> (Cursor up)
-///     and <c>\x1b[1;5A</c> (Cursor up with Ctrl)
+///     and <c>\x1b[1;5A</c> (Cursor/Function with modifier(s))
 /// </summary>
 public class CsiCursorPattern : AnsiKeyboardParserPattern
 {
-    private readonly Regex _pattern = new (@"^\u001b\[(?:1;(\d+))?([A-DHF])$");
+    private readonly Regex _pattern = new (@"^\u001b\[(?:1;(\d+))?([A-DFHPQRS])$");
 
     private readonly Dictionary<char, Key> _cursorMap = new ()
     {
@@ -20,7 +20,13 @@ public class CsiCursorPattern : AnsiKeyboardParserPattern
         { 'C', Key.CursorRight },
         { 'D', Key.CursorLeft },
         { 'H', Key.Home },
-        { 'F', Key.End }
+        { 'F', Key.End },
+
+        // F1–F4 as per xterm VT100-style CSI sequences
+        { 'P', Key.F1 },
+        { 'Q', Key.F2 },
+        { 'R', Key.F3 },
+        { 'S', Key.F4 }
     };
 
     /// <inheritdoc/>

+ 5 - 3
Terminal.Gui/ViewBase/Layout/Dim.cs

@@ -141,12 +141,14 @@ public abstract record Dim : IEqualityOperators<Dim, Dim, bool>
     public static Dim? Fill (Dim margin) { return new DimFill (margin); }
 
     /// <summary>
-    ///     Creates a function <see cref="Dim"/> object that computes the dimension by executing the provided function.
+    ///     Creates a function <see cref="Dim"/> object that computes the dimension based on the passed view and by executing
+    ///     the provided function.
     ///     The function will be called every time the dimension is needed.
     /// </summary>
     /// <param name="function">The function to be executed.</param>
-    /// <returns>The <see cref="Dim"/> returned from the function.</returns>
-    public static Dim Func (Func<int> function) { return new DimFunc (function); }
+    /// <param name="view">The view where the data will be retrieved.</param>
+    /// <returns>The <see cref="Dim"/> returned from the function based on the passed view.</returns>
+    public static Dim Func (Func<View?, int> function, View? view = null) { return new DimFunc (function, view); }
 
     /// <summary>Creates a <see cref="Dim"/> object that tracks the Height of the specified <see cref="View"/>.</summary>
     /// <returns>The height <see cref="Dim"/> of the other <see cref="View"/>.</returns>

+ 2 - 2
Terminal.Gui/ViewBase/Layout/DimAuto.cs

@@ -48,7 +48,7 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt
                     us.TextFormatter.ConstrainToSize = us.TextFormatter.FormatAndGetSize (new (int.Min (autoMax, screenX4), screenX4));
                 }
 
-                textSize = us.TextFormatter.ConstrainToWidth!.Value;
+                textSize = us.TextFormatter.ConstrainToWidth ?? 0;
             }
             else
             {
@@ -81,7 +81,7 @@ public record DimAuto (Dim? MaximumContentDim, Dim? MinimumContentDim, DimAutoSt
             {
                 // TOOD: All the below is a naive implementation. It may be possible to optimize this.
 
-                List<View> includedSubViews = us.InternalSubViews.ToList ();
+                List<View> includedSubViews = us.SubViews.Snapshot ().ToList ();
 
                 // If [x] it can cause `us.ContentSize` to change.
                 // If [ ] it doesn't need special processing for us to determine `us.ContentSize`.

+ 13 - 6
Terminal.Gui/ViewBase/Layout/DimFunc.cs

@@ -2,22 +2,29 @@
 namespace Terminal.Gui.ViewBase;
 
 /// <summary>
-///     Represents a function <see cref="Dim"/> object that computes the dimension by executing the provided function.
+///     Represents a function <see cref="Dim"/> object that computes the dimension based on the passed view and by
+///     executing the provided function.
 /// </summary>
 /// <remarks>
 ///     This is a low-level API that is typically used internally by the layout system. Use the various static
 ///     methods on the <see cref="Dim"/> class to create <see cref="Dim"/> objects instead.
 /// </remarks>
 /// <param name="Fn">The function that computes the dimension. If this function throws <see cref="LayoutException"/>... </param>
-public record DimFunc (Func<int> Fn) : Dim
+/// <param name="View">The <see cref="Dim"/> returned from the function based on the passed view.</param>
+public record DimFunc (Func<View?, int> Fn, View? View = null) : Dim
 {
     /// <summary>
     ///     Gets the function that computes the dimension.
     /// </summary>
-    public Func<int> Fn { get; } = Fn;
+    public Func<View?, int> Fn { get; } = Fn;
+
+    /// <summary>
+    ///     Gets the passed view that the dimension is based on.
+    /// </summary>
+    public View? View { get; } = View;
 
     /// <inheritdoc/>
-    public override string ToString () { return $"DimFunc({Fn ()})"; }
+    public override string ToString () { return $"DimFunc({Fn (View)})"; }
 
-    internal override int GetAnchor (int size) { return Fn (); }
-}
+    internal override int GetAnchor (int size) { return Fn (View); }
+}

+ 5 - 3
Terminal.Gui/ViewBase/Layout/Pos.cs

@@ -220,12 +220,14 @@ public abstract record Pos
     public static Pos Center () { return new PosCenter (); }
 
     /// <summary>
-    ///     Creates a <see cref="Pos"/> object that computes the position by executing the provided function. The function
-    ///     will be called every time the position is needed.
+    ///     Creates a <see cref="Pos"/> object that computes the position based on the passed view and by executing the
+    ///     provided function.
+    ///     The function will be called every time the position is needed.
     /// </summary>
     /// <param name="function">The function to be executed.</param>
+    /// <param name="view">The view where the data will be retrieved.</param>
     /// <returns>The <see cref="Pos"/> returned from the function.</returns>
-    public static Pos Func (Func<int> function) { return new PosFunc (function); }
+    public static Pos Func (Func<View?, int> function, View? view = null) { return new PosFunc (function, view); }
 
     /// <summary>Creates a percentage <see cref="Pos"/> object</summary>
     /// <returns>The percent <see cref="Pos"/> object.</returns>

+ 1 - 1
Terminal.Gui/ViewBase/Layout/PosAlign.cs

@@ -117,7 +117,7 @@ public record PosAlign : Pos
         }
         else
         {
-            groupViews = us.SuperView!.SubViews.Where (v => HasGroupId (v, dimension, GroupId)).ToList ();
+            groupViews = us.SuperView!.SubViews.Snapshot ().Where (v => HasGroupId (v, dimension, GroupId)).ToList ();
         }
 
         AlignAndUpdateGroup (GroupId, groupViews, dimension, superviewDimension);

+ 19 - 4
Terminal.Gui/ViewBase/Layout/PosFunc.cs

@@ -4,11 +4,26 @@ namespace Terminal.Gui.ViewBase;
 /// <summary>
 ///     Represents a position that is computed by executing a function that returns an integer position.
 /// </summary>
-/// <param name="Fn">The function that computes the dimension. If this function throws <see cref="LayoutException"/>... </param>
-public record PosFunc (Func<int> Fn) : Pos
+/// <remarks>
+///     This is a low-level API that is typically used internally by the layout system. Use the various static
+///     methods on the <see cref="Pos"/> class to create <see cref="Pos"/> objects instead.
+/// </remarks>
+/// <param name="Fn">The function that computes the position. If this function throws <see cref="LayoutException"/>... </param>
+/// <param name="View">The <see cref="Pos"/> returned from the function based on the passed view.</param>
+public record PosFunc (Func<View?, int> Fn, View? View = null) : Pos
 {
+    /// <summary>
+    ///     Gets the function that computes the position.
+    /// </summary>
+    public Func<View?, int> Fn { get; } = Fn;
+
+    /// <summary>
+    ///     Gets the passed view that the position is based on.
+    /// </summary>
+    public View? View { get; } = View;
+
     /// <inheritdoc/>
-    public override string ToString () { return $"PosFunc({Fn ()})"; }
+    public override string ToString () { return $"PosFunc({Fn (View)})"; }
 
-    internal override int GetAnchor (int size) { return Fn (); }
+    internal override int GetAnchor (int size) { return Fn (View); }
 }

+ 32 - 11
Terminal.Gui/ViewBase/View.Drawing.cs

@@ -1,5 +1,6 @@
 #nullable enable
 using System.ComponentModel;
+using System.Diagnostics;
 
 namespace Terminal.Gui.ViewBase;
 
@@ -12,7 +13,8 @@ public partial class View // Drawing APIs
     /// <param name="force">If <see langword="true"/>, <see cref="View.SetNeedsDraw()"/> will be called on each view to force it to be drawn.</param>
     internal static void Draw (IEnumerable<View> views, bool force)
     {
-        IEnumerable<View> viewsArray = views as View [] ?? views.ToArray ();
+        // **Snapshot once** — every recursion level gets its own frozen array
+        View [] viewsArray = views.Snapshot ();
 
         // The draw context is used to track the region drawn by each view.
         DrawContext context = new DrawContext ();
@@ -111,6 +113,26 @@ public partial class View // Drawing APIs
             Border?.AdvanceDrawIndicator ();
 
             ClearNeedsDraw ();
+
+            if (this is not Adornment && SuperView is not Adornment)
+            {
+                // Parent
+                Debug.Assert (Margin!.Parent == this);
+                Debug.Assert (Border!.Parent == this);
+                Debug.Assert (Padding!.Parent == this);
+
+                // SubViewNeedsDraw is set to false by ClearNeedsDraw.
+                Debug.Assert (SubViewNeedsDraw == false);
+                Debug.Assert (Margin!.SubViewNeedsDraw == false);
+                Debug.Assert (Border!.SubViewNeedsDraw == false);
+                Debug.Assert (Padding!.SubViewNeedsDraw == false);
+
+                // NeedsDraw is set to false by ClearNeedsDraw.
+                Debug.Assert (NeedsDraw == false);
+                Debug.Assert (Margin!.NeedsDraw == false);
+                Debug.Assert (Border!.NeedsDraw == false);
+                Debug.Assert (Padding!.NeedsDraw == false);
+            }
         }
 
         // ------------------------------------
@@ -549,7 +571,7 @@ public partial class View // Drawing APIs
         }
 
         // Draw the subviews in reverse order to leverage clipping.
-        foreach (View view in InternalSubViews.Where (view => view.Visible).Reverse ())
+        foreach (View view in InternalSubViews.Snapshot ().Where (v => v.Visible).Reverse ())
         {
             // TODO: HACK - This forcing of SetNeedsDraw with SuperViewRendersLineCanvas enables auto line join to work, but is brute force.
             if (view.SuperViewRendersLineCanvas || view.ViewportSettings.HasFlag (ViewportSettingsFlags.Transparent))
@@ -720,8 +742,7 @@ public partial class View // Drawing APIs
     /// </remarks>
     public bool NeedsDraw
     {
-        // TODO: Figure out if we can decouple NeedsDraw from NeedsLayout.
-        get => Visible && (NeedsDrawRect != Rectangle.Empty || NeedsLayout);
+        get => Visible && (NeedsDrawRect != Rectangle.Empty || Margin?.NeedsDraw == true || Border?.NeedsDraw == true || Padding?.NeedsDraw == true);
         set
         {
             if (value)
@@ -806,8 +827,8 @@ public partial class View // Drawing APIs
             adornment.Parent?.SetSubViewNeedsDraw ();
         }
 
-        // There was multiple enumeration error here, so calling ToArray - probably a stop gap
-        foreach (View subview in InternalSubViews)
+        // There was multiple enumeration error here, so calling new snapshot collection - probably a stop gap
+        foreach (View subview in InternalSubViews.Snapshot ())
         {
             if (subview.Frame.IntersectsWith (viewPortRelativeRegion))
             {
@@ -846,22 +867,23 @@ public partial class View // Drawing APIs
         NeedsDrawRect = Rectangle.Empty;
         SubViewNeedsDraw = false;
 
-        if (Margin is { } && Margin.Thickness != Thickness.Empty)
+        if (Margin is { } && (Margin.Thickness != Thickness.Empty || Margin.SubViewNeedsDraw || Margin.NeedsDraw))
         {
             Margin?.ClearNeedsDraw ();
         }
 
-        if (Border is { } && Border.Thickness != Thickness.Empty)
+        if (Border is { } && (Border.Thickness != Thickness.Empty || Border.SubViewNeedsDraw || Border.NeedsDraw))
         {
             Border?.ClearNeedsDraw ();
         }
 
-        if (Padding is { } && Padding.Thickness != Thickness.Empty)
+        if (Padding is { } && (Padding.Thickness != Thickness.Empty || Padding.SubViewNeedsDraw || Padding.NeedsDraw))
         {
             Padding?.ClearNeedsDraw ();
         }
 
-        foreach (View subview in SubViews)
+        // There was multiple enumeration error here, so calling new snapshot collection - probably a stop gap
+        foreach (View subview in InternalSubViews.Snapshot ())
         {
             subview.ClearNeedsDraw ();
         }
@@ -876,7 +898,6 @@ public partial class View // Drawing APIs
         {
             LineCanvas.Clear ();
         }
-
     }
 
     #endregion NeedsDraw

+ 9 - 4
Terminal.Gui/ViewBase/View.Layout.cs

@@ -419,7 +419,10 @@ public partial class View // Layout APIs
         {
             LayoutSubViews ();
 
-            // Debug.Assert(!NeedsLayout);
+            // A layout was performed so a draw is needed
+            // NeedsLayout may still be true if a dependent View still needs layout after SubViewsLaidOut event
+            SetNeedsDraw ();
+
             return true;
         }
 
@@ -635,7 +638,7 @@ public partial class View // Layout APIs
 
         List<View> redo = new ();
 
-        foreach (View v in ordered)
+        foreach (View v in ordered.Snapshot ())
         {
             if (!v.Layout (contentSize))
             {
@@ -700,7 +703,7 @@ public partial class View // Layout APIs
     ///     Override to perform tasks after the <see cref="View"/> has been resized or the layout has
     ///     otherwise changed.
     /// </remarks>
-    protected virtual void OnSubViewsLaidOut (LayoutEventArgs args) { }
+    protected virtual void OnSubViewsLaidOut (LayoutEventArgs args) { Debug.Assert (!NeedsLayout); }
 
     /// <summary>Raised after all sub-views have been laid out.</summary>
     /// <remarks>
@@ -761,10 +764,12 @@ public partial class View // Layout APIs
 
         // TODO: Optimize this - see Setting_Thickness_Causes_Adornment_SubView_Layout
         // Use a stack to avoid recursion
-        Stack<View> stack = new (SubViews);
+        Stack<View> stack = new (InternalSubViews.Snapshot ().ToList ());
 
         while (stack.Count > 0)
         {
+            Debug.Assert (stack.Peek () is { });
+
             View current = stack.Pop ();
 
             if (!current.NeedsLayout)

+ 2 - 2
Terminal.Gui/ViewBase/View.ScrollBars.cs

@@ -73,7 +73,7 @@ public partial class View
 
         scrollBar.Height = Dim.Fill (
                                      Dim.Func (
-                                               () =>
+                                               _ =>
                                                {
                                                    if (_horizontalScrollBar.IsValueCreated)
                                                    {
@@ -98,7 +98,7 @@ public partial class View
 
         scrollBar.Width = Dim.Fill (
                                     Dim.Func (
-                                              () =>
+                                              _ =>
                                               {
                                                   if (_verticalScrollBar.IsValueCreated)
                                                   {

+ 20 - 0
Terminal.Gui/ViewBase/ViewCollectionHelpers.cs

@@ -0,0 +1,20 @@
+namespace Terminal.Gui.ViewBase;
+
+internal static class ViewCollectionHelpers
+{
+    /// <summary>Returns a defensive copy of any <see cref="IEnumerable{T}"/>.</summary>
+    internal static View [] Snapshot (this IEnumerable<View> source)
+    {
+        if (source is IList<View> list)
+        {
+            // The list parameter might be the live `_subviews`, so freeze it under a lock
+            lock (list)
+            {
+                return [.. list]; // C# 12 slice copy (= new List<View>(list).ToArray())
+            }
+        }
+
+        // Anything else (LINQ result, iterator block, etc.) we just enumerate.
+        return source.ToArray (); // Safe because it’s not shared mutable state
+    }
+}

+ 2 - 2
Terminal.Gui/Views/FileDialogs/FileDialog.cs

@@ -154,7 +154,7 @@ public class FileDialog : Dialog, IDesignable
             X = 0,
             Y = Pos.Bottom (_btnBack),
             Width = Dim.Fill (),
-            Height = Dim.Fill (Dim.Func (() => IsInitialized ? _btnOk.Frame.Height : 1))
+            Height = Dim.Fill (Dim.Func (_ => IsInitialized ? _btnOk.Frame.Height : 1))
         };
 
         Initialized += (s, e) =>
@@ -754,7 +754,7 @@ public class FileDialog : Dialog, IDesignable
         return (Style.IconProvider.GetIconWithOptionalSpace (fsi) + fsi.Name).Trim ();
     }
 
-    private int CalculateOkButtonPosX ()
+    private int CalculateOkButtonPosX (View? _)
     {
         if (!IsInitialized || !_btnOk.IsInitialized || !_btnCancel.IsInitialized)
         {

+ 2 - 2
Terminal.Gui/Views/Menu/Menuv2.cs

@@ -93,8 +93,8 @@ public class Menuv2 : Bar
                 }
             case Line line:
                 // Grow line so we get auto-join line
-                line.X = Pos.Func (() => -Border!.Thickness.Left);
-                line.Width = Dim.Fill ()! + Dim.Func (() => Border!.Thickness.Right);
+                line.X = Pos.Func (_ => -Border!.Thickness.Left);
+                line.Width = Dim.Fill ()! + Dim.Func (_ => Border!.Thickness.Right);
 
                 break;
         }

+ 1 - 1
Terminal.Gui/Views/Menuv1/Menu.cs

@@ -527,7 +527,7 @@ internal sealed class Menu : View
 
     private void Application_UnGrabbedMouse (object? sender, ViewEventArgs a)
     {
-        if (_host.IsMenuOpen)
+        if (_host is { IsMenuOpen: true })
         {
             _host.CloseAllMenus ();
         }

+ 4 - 4
Terminal.Gui/Views/MessageBox.cs

@@ -394,12 +394,12 @@ public static class MessageBox
         };
 
         d.Width = Dim.Auto (DimAutoStyle.Auto,
-                            minimumContentDim: Dim.Func (() => (int)((Application.Screen.Width - d.GetAdornmentsThickness ().Horizontal) * (DefaultMinimumWidth / 100f))),
-                            maximumContentDim: Dim.Func (() => (int)((Application.Screen.Width - d.GetAdornmentsThickness ().Horizontal) * 0.9f)));
+                            minimumContentDim: Dim.Func (_ => (int)((Application.Screen.Width - d.GetAdornmentsThickness ().Horizontal) * (DefaultMinimumWidth / 100f))),
+                            maximumContentDim: Dim.Func (_ => (int)((Application.Screen.Width - d.GetAdornmentsThickness ().Horizontal) * 0.9f)));
 
         d.Height = Dim.Auto (DimAutoStyle.Auto,
-                             minimumContentDim: Dim.Func (() => (int)((Application.Screen.Height - d.GetAdornmentsThickness ().Vertical) * (DefaultMinimumHeight / 100f))),
-                             maximumContentDim: Dim.Func (() => (int)((Application.Screen.Height - d.GetAdornmentsThickness ().Vertical) * 0.9f)));
+                             minimumContentDim: Dim.Func (_ => (int)((Application.Screen.Height - d.GetAdornmentsThickness ().Vertical) * (DefaultMinimumHeight / 100f))),
+                             maximumContentDim: Dim.Func (_ => (int)((Application.Screen.Height - d.GetAdornmentsThickness ().Vertical) * 0.9f)));
 
 
         if (width != 0)

+ 1 - 1
Terminal.Gui/Views/NumericUpDown.cs

@@ -62,7 +62,7 @@ public class NumericUpDown<T> : View where T : notnull
             Text = Value?.ToString () ?? "Err",
             X = Pos.Right (_down),
             Y = Pos.Top (_down),
-            Width = Dim.Auto (minimumContentDim: Dim.Func (() => string.Format (Format, Value).GetColumns())),
+            Width = Dim.Auto (minimumContentDim: Dim.Func (_ => string.Format (Format, Value).GetColumns())),
             Height = 1,
             TextAlignment = Alignment.Center,
             CanFocus = true,

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

@@ -40,11 +40,11 @@ public class ScrollBar : View, IOrientation, IDesignable
         // Set the default width and height based on the orientation - fill Viewport
         Width = Dim.Auto (
                           DimAutoStyle.Content,
-                          Dim.Func (() => Orientation == Orientation.Vertical ? 1 : SuperView?.Viewport.Width ?? 0));
+                          Dim.Func (_ => Orientation == Orientation.Vertical ? 1 : SuperView?.Viewport.Width ?? 0));
 
         Height = Dim.Auto (
                            DimAutoStyle.Content,
-                           Dim.Func (() => Orientation == Orientation.Vertical ? SuperView?.Viewport.Height ?? 0 : 1));
+                           Dim.Func (_ => Orientation == Orientation.Vertical ? SuperView?.Viewport.Height ?? 0 : 1));
 
         _decreaseButton = new ()
         {

+ 4 - 4
Terminal.Gui/Views/Shortcut.cs

@@ -106,8 +106,8 @@ public class Shortcut : View, IOrientation, IDesignable
     {
         return Dim.Auto (
                          DimAutoStyle.Content,
-                         minimumContentDim: Dim.Func (() => _minimumNaturalWidth ?? 0),
-                         maximumContentDim: Dim.Func (() => _minimumNaturalWidth ?? 0))!;
+                         minimumContentDim: Dim.Func (_ => _minimumNaturalWidth ?? 0),
+                         maximumContentDim: Dim.Func (_ => _minimumNaturalWidth ?? 0))!;
     }
 
     private AlignmentModes _alignmentModes = AlignmentModes.StartToEnd | AlignmentModes.IgnoreFirstOrLast;
@@ -540,7 +540,7 @@ public class Shortcut : View, IOrientation, IDesignable
 
         HelpView.X = Pos.Align (Alignment.End, AlignmentModes);
         _maxHelpWidth = HelpView.Text.GetColumns ();
-        HelpView.Width = Dim.Auto (DimAutoStyle.Text, maximumContentDim: Dim.Func ((() => _maxHelpWidth)));
+        HelpView.Width = Dim.Auto (DimAutoStyle.Text, maximumContentDim: Dim.Func ((_ => _maxHelpWidth)));
         HelpView.Height = Dim.Fill ();
 
         HelpView.Visible = true;
@@ -672,7 +672,7 @@ public class Shortcut : View, IOrientation, IDesignable
         }
 
         KeyView.X = Pos.Align (Alignment.End, AlignmentModes);
-        KeyView.Width = Dim.Auto (DimAutoStyle.Text, minimumContentDim: Dim.Func (() => MinimumKeyTextSize));
+        KeyView.Width = Dim.Auto (DimAutoStyle.Text, minimumContentDim: Dim.Func (_ => MinimumKeyTextSize));
         KeyView.Height = Dim.Fill ();
 
         KeyView.Visible = true;

+ 4 - 4
Terminal.Gui/Views/Wizard/Wizard.cs

@@ -490,7 +490,7 @@ public class Wizard : Dialog
 
             step.Height = Dim.Fill (
                                     Dim.Func (
-                                              () => IsInitialized
+                                              v => IsInitialized
                                                         ? SubViews.First (view => view.Y.Has<PosAnchorEnd> (out _)).Frame.Height + 1
                                                         : 1)); // for button frame (+1 for lineView)
             step.Width = Dim.Fill ();
@@ -502,9 +502,9 @@ public class Wizard : Dialog
 
             step.Height = Dim.Fill (
                                     Dim.Func (
-                                              () => IsInitialized
-                                                        ? SubViews.First (view => view.Y.Has<PosAnchorEnd> (out _)).Frame.Height + 1
-                                                        : 2)); // for button frame (+1 for lineView)
+                                              v => IsInitialized
+                                                       ? SubViews.First (view => view.Y.Has<PosAnchorEnd> (out _)).Frame.Height + 1
+                                                       : 2)); // for button frame (+1 for lineView)
             step.Width = Dim.Fill ();
         }
     }

+ 78 - 58
Tests/TerminalGuiFluentTesting/GuiTestContext.cs

@@ -25,75 +25,95 @@ public class GuiTestContext : IDisposable
 
     internal GuiTestContext (Func<Toplevel> topLevelBuilder, int width, int height, V2TestDriver driver)
     {
-        IApplication origApp = ApplicationImpl.Instance;
-        ILogger? origLogger = Logging.Logger;
-        _logsSb = new ();
-        _driver = driver;
-
-        _netInput = new (_cts.Token);
-        _winInput = new (_cts.Token);
-
-        _output.Size = new (width, height);
-
-        var v2 = new ApplicationV2 (
-                                    () => _netInput,
-                                    () => _output,
-                                    () => _winInput,
-                                    () => _output);
-
-        var booting = new SemaphoreSlim (0, 1);
-
         lock (_threadLock)
         {
-            // Start the application in a background thread
-            _runTask = Task.Run (
-                                 () =>
-                                 {
-                                     try
-                                     {
-                                         ApplicationImpl.ChangeInstance (v2);
+            IApplication origApp = ApplicationImpl.Instance;
+            ILogger? origLogger = Logging.Logger;
+            _logsSb = new ();
+            _driver = driver;
 
-                                         ILogger logger = LoggerFactory.Create (
-                                                                                builder =>
-                                                                                    builder.SetMinimumLevel (LogLevel.Trace)
-                                                                                           .AddProvider (new TextWriterLoggerProvider (new StringWriter (_logsSb))))
-                                                                       .CreateLogger ("Test Logging");
-                                         Logging.Logger = logger;
+            _netInput = new (_cts.Token);
+            _winInput = new (_cts.Token);
 
-                                         v2.Init (null, GetDriverName ());
+            _output.Size = new (width, height);
 
-                                         booting.Release ();
+            var v2 = new ApplicationV2 (
+                                        () => _netInput,
+                                        () => _output,
+                                        () => _winInput,
+                                        () => _output);
 
-                                         Toplevel t = topLevelBuilder ();
-                                         t.Closed += (s, e) => { _finished = true; };
-                                         Application.Run (t); // This will block, but it's on a background thread now
+            var booting = new SemaphoreSlim (0, 1);
 
-                                         t.Dispose ();
-                                         Application.Shutdown ();
-                                     }
-                                     catch (OperationCanceledException)
-                                     { }
-                                     catch (Exception ex)
-                                     {
-                                         _ex = ex;
-                                     }
-                                     finally
+            // Start the application in a background thread
+            _runTask = Task.Run (() =>
+                                 {
+                                     while (Application.Top is { })
                                      {
-                                         ApplicationImpl.ChangeInstance (origApp);
-                                         Logging.Logger = origLogger;
-                                         _finished = true;
+                                         Task.Delay (300).Wait ();
                                      }
-                                 },
-                                 _cts.Token);
-        }
+                                 })
+                           .ContinueWith (
+                                          (task, _) =>
+                                          {
+                                              try
+                                              {
+                                                  if (task.IsFaulted)
+                                                  {
+                                                      _ex = task.Exception ?? new Exception ("Unknown error in background task");
+                                                  }
+
+                                                  // Ensure we are not running on the main thread
+                                                  if (ApplicationImpl.Instance != origApp)
+                                                  {
+                                                      throw new InvalidOperationException (
+                                                                                           "Application instance is not the original one, this should not happen.");
+                                                  }
+
+                                                  ApplicationImpl.ChangeInstance (v2);
+
+                                                  ILogger logger = LoggerFactory.Create (builder =>
+                                                                                             builder.SetMinimumLevel (LogLevel.Trace)
+                                                                                                    .AddProvider (
+                                                                                                         new TextWriterLoggerProvider (
+                                                                                                              new StringWriter (_logsSb))))
+                                                                                .CreateLogger ("Test Logging");
+                                                  Logging.Logger = logger;
+
+                                                  v2.Init (null, GetDriverName ());
+
+                                                  booting.Release ();
+
+                                                  Toplevel t = topLevelBuilder ();
+                                                  t.Closed += (s, e) => { _finished = true; };
+                                                  Application.Run (t); // This will block, but it's on a background thread now
+
+                                                  t.Dispose ();
+                                                  Application.Shutdown ();
+                                              }
+                                              catch (OperationCanceledException)
+                                              { }
+                                              catch (Exception ex)
+                                              {
+                                                  _ex = ex;
+                                              }
+                                              finally
+                                              {
+                                                  ApplicationImpl.ChangeInstance (origApp);
+                                                  Logging.Logger = origLogger;
+                                                  _finished = true;
+                                              }
+                                          },
+                                          _cts.Token);
+
+            // Wait for booting to complete with a timeout to avoid hangs
+            if (!booting.WaitAsync (TimeSpan.FromSeconds (10)).Result)
+            {
+                throw new TimeoutException ("Application failed to start within the allotted time.");
+            }
 
-        // Wait for booting to complete with a timeout to avoid hangs
-        if (!booting.WaitAsync (TimeSpan.FromSeconds (10)).Result)
-        {
-            throw new TimeoutException ("Application failed to start within the allotted time.");
+            WaitIteration ();
         }
-
-        WaitIteration ();
     }
 
     private string GetDriverName ()

+ 1 - 2
Tests/UnitTests/ConsoleDrivers/AnsiKeyboardParserTests.cs

@@ -100,11 +100,10 @@ public class AnsiKeyboardParserTests
         yield return new object [] { "\u001b[24~", Key.F12 };
 
         // Function keys with modifiers
-        /*  Not currently supported
         yield return new object [] { "\u001b[1;2P", Key.F1.WithShift };
         yield return new object [] { "\u001b[1;3Q", Key.F2.WithAlt };
         yield return new object [] { "\u001b[1;5R", Key.F3.WithCtrl };
-        */
+        
     }
 
     // Consolidated test for all keyboard events (e.g., arrow keys)

+ 0 - 1
Tests/UnitTests/View/Draw/ClearViewportTests.cs

@@ -114,7 +114,6 @@ public class ClearViewportTests (ITestOutputHelper output)
         superView.BeginInit ();
         superView.EndInit ();
         superView.LayoutSubViews ();
-
         superView.Draw ();
 
         DriverAssert.AssertDriverContentsWithFrameAre (

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

@@ -94,7 +94,7 @@ public class LabelTests (ITestOutputHelper output)
     public void Text_Set_With_AnchorEnd_Works ()
     {
         var label = new Label { Y = Pos.Center (), Text = "Say Hello 你" };
-        label.X = Pos.AnchorEnd (0) - Pos.Func (() => label.TextFormatter.Text.GetColumns ());
+        label.X = Pos.AnchorEnd (0) - Pos.Func (_ => label.TextFormatter.Text.GetColumns ());
 
         var win = new Window { Width = Dim.Fill (), Height = Dim.Fill () };
         win.Add (label);

+ 9 - 1
Tests/UnitTests/Views/TileViewTests.cs

@@ -819,6 +819,10 @@ public class TileViewTests (ITestOutputHelper output)
                              Assert.Equal (1, myReusableView.DisposalCount);
                          }
                         );
+
+        Assert.NotNull (Application.Top);
+        Application.Top.Dispose ();
+        Application.Shutdown ();
     }
 
     [Theory]
@@ -848,6 +852,10 @@ public class TileViewTests (ITestOutputHelper output)
                              Assert.True (myReusableView.DisposalCount >= 1);
                          }
                         );
+
+        Assert.NotNull (Application.Top);
+        Application.Top.Dispose ();
+        Application.Shutdown ();
     }
 
     [Fact]
@@ -1606,7 +1614,7 @@ public class TileViewTests (ITestOutputHelper output)
         var ex = Assert.Throws<ArgumentException> (() => tileView.SetSplitterPos (0, Pos.Right (tileView)));
         Assert.Equal ("Only Percent and Absolute values are supported. Passed value was PosView", ex.Message);
 
-        ex = Assert.Throws<ArgumentException> (() => tileView.SetSplitterPos (0, Pos.Func (() => 1)));
+        ex = Assert.Throws<ArgumentException> (() => tileView.SetSplitterPos (0, Pos.Func (_ => 1)));
         Assert.Equal ("Only Percent and Absolute values are supported. Passed value was PosFunc", ex.Message);
 
         // Also not allowed because this results in a PosCombine

+ 33 - 17
Tests/UnitTestsParallelizable/View/Draw/NeedsDrawTests.cs

@@ -10,7 +10,7 @@ public class NeedsDrawTests
         View view = new () { Width = 0, Height = 0 };
         view.BeginInit ();
         view.EndInit ();
-        Assert.True (view.NeedsDraw);
+        Assert.False (view.NeedsDraw);
 
         //Assert.False (view.SubViewNeedsDraw);
     }
@@ -70,14 +70,16 @@ public class NeedsDrawTests
         view.NeedsDraw = false;
 
         view.BeginInit ();
-        Assert.True (view.NeedsDraw); // Because layout is still needed
+        Assert.False (view.NeedsDraw); // Because layout is still needed
 
         view.Layout ();
-        Assert.False (view.NeedsDraw);
+        // NeedsDraw is true after layout and NeedsLayout is false if SubViewsLaidOut doesn't call SetNeedsLayout
+        Assert.True (view.NeedsDraw);
+        Assert.False (view.NeedsLayout);
     }
 
     [Fact]
-    public void NeedsDraw_False_After_EndInit ()
+    public void NeedsDraw_True_After_EndInit_Where_Call_Layout ()
     {
         var view = new View { Width = 2, Height = 2, BorderStyle = LineStyle.Single };
         Assert.True (view.NeedsDraw);
@@ -96,7 +98,7 @@ public class NeedsDrawTests
     }
 
     [Fact]
-    public void NeedsDraw_After_SetLayoutNeeded ()
+    public void NeedsDraw_After_SetLayoutNeeded_And_Layout ()
     {
         var view = new View { Width = 2, Height = 2 };
         Assert.True (view.NeedsDraw);
@@ -107,8 +109,12 @@ public class NeedsDrawTests
         Assert.False (view.NeedsLayout);
 
         view.SetNeedsLayout ();
-        Assert.True (view.NeedsDraw);
+        Assert.False (view.NeedsDraw);
         Assert.True (view.NeedsLayout);
+
+        view.Layout ();
+        Assert.True (view.NeedsDraw);
+        Assert.False (view.NeedsLayout);
     }
 
     [Fact]
@@ -121,21 +127,27 @@ public class NeedsDrawTests
         Assert.False (view.NeedsDraw);
         Assert.False (view.NeedsLayout);
 
-        // SRL won't change anything since the view is Absolute
+        // SRL won't change anything since the view frame wasn't changed
         view.SetRelativeLayout (Application.Screen.Size);
         Assert.False (view.NeedsDraw);
 
         view.SetNeedsLayout ();
 
-        // SRL won't change anything since the view is Absolute
+        // SRL won't change anything since the view frame wasn't changed
+        // SRL doesn't depend on NeedsLayout, but LayoutSubViews does
         view.SetRelativeLayout (Application.Screen.Size);
+        Assert.False (view.NeedsDraw);
+        Assert.True (view.NeedsLayout);
+
+        view.Layout ();
         Assert.True (view.NeedsDraw);
+        Assert.False (view.NeedsLayout);
 
         view.NeedsDraw = false;
 
-        // SRL won't change anything since the view is Absolute. However, Layout has not been called
+        // SRL won't change anything since the view frame wasn't changed. However, Layout has not been called
         view.SetRelativeLayout (new (10, 10));
-        Assert.True (view.NeedsDraw);
+        Assert.False (view.NeedsDraw);
     }
 
     [Fact]
@@ -149,17 +161,20 @@ public class NeedsDrawTests
             Width = Dim.Fill (),
             Height = Dim.Fill ()
         };
-        Assert.True (superView.NeedsDraw);
+
+        // A layout wasn't called yet, so NeedsDraw is still empty
+        Assert.False (superView.NeedsDraw);
 
         superView.Add (view);
-        Assert.True (view.NeedsDraw);
-        Assert.True (superView.NeedsDraw);
+        // A layout wasn't called yet, so NeedsDraw is still empty
+        Assert.False (view.NeedsDraw);
+        Assert.False (superView.NeedsDraw);
 
         superView.BeginInit ();
-        Assert.True (view.NeedsDraw);
-        Assert.True (superView.NeedsDraw);
+        Assert.False (view.NeedsDraw);
+        Assert.False (superView.NeedsDraw);
 
-        superView.EndInit ();
+        superView.EndInit (); // Call Layout
         Assert.True (view.NeedsDraw);
         Assert.True (superView.NeedsDraw);
 
@@ -177,9 +192,10 @@ public class NeedsDrawTests
             Width = Dim.Fill (),
             Height = Dim.Fill ()
         };
-        Assert.True (superView.NeedsDraw);
+        Assert.False (superView.NeedsDraw);
 
         superView.Layout ();
+        Assert.True (superView.NeedsDraw);
 
         superView.NeedsDraw = false;
         superView.SetRelativeLayout (new (10, 10));

+ 1 - 1
Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.DimTypes.cs

@@ -179,7 +179,7 @@ public partial class DimAutoTests
     public void With_SubView_Using_DimFunc ()
     {
         var view = new View ();
-        var subview = new View { Width = Dim.Func (() => 20), Height = Dim.Func (() => 25) };
+        var subview = new View { Width = Dim.Func (_ => 20), Height = Dim.Func (_ => 25) };
         view.Add (subview);
 
         subview.SetRelativeLayout (new (100, 100));

+ 2 - 1
Tests/UnitTestsParallelizable/View/Layout/Dim.AutoTests.PosTypes.cs

@@ -577,6 +577,7 @@ public partial class DimAutoTests
         Assert.Equal (view.Viewport.Width - subview.Frame.Width, subview.Frame.X);
         Assert.Equal (view.Viewport.Height - subview.Frame.Height, subview.Frame.Y);
     }
+
     [Theory]
     [InlineData (0, 10, 0, 10, 10, 2)]
     [InlineData (0, 5, 0, 5, 5, 3)] // max width of 5 should cause wordwrap at 5 giving a height of 2 + 1
@@ -638,7 +639,7 @@ public partial class DimAutoTests
             Width = Dim.Auto (),
             Height = Dim.Auto (),
         };
-        var subview = new View { X = Pos.Func (() => 20), Y = Pos.Func (() => 25) };
+        var subview = new View { X = Pos.Func (_ => 20), Y = Pos.Func (_ => 25) };
         view.Add (subview);
 
         view.SetRelativeLayout (new (100, 100));

+ 2 - 2
Tests/UnitTestsParallelizable/View/Layout/Dim.FillTests.cs

@@ -123,12 +123,12 @@ public class DimFillTests (ITestOutputHelper output)
     [Fact]
     public void DimFill_Margin_Is_Dim_SetsValue ()
     {
-        Dim testMargin = Dim.Func (() => 0);
+        Dim testMargin = Dim.Func (_ => 0);
         Dim dim = Dim.Fill (testMargin);
         Assert.Equal (0, dim!.GetAnchor (0));
 
 
-        testMargin = Dim.Func (() => 5);
+        testMargin = Dim.Func (_ => 5);
         dim = Dim.Fill (testMargin);
         Assert.Equal (-5, dim!.GetAnchor (0));
     }

+ 48 - 5
Tests/UnitTestsParallelizable/View/Layout/Dim.FuncTests.cs

@@ -10,8 +10,8 @@ public class DimFuncTests (ITestOutputHelper output)
     [Fact]
     public void DimFunc_Equal ()
     {
-        Func<int> f1 = () => 0;
-        Func<int> f2 = () => 0;
+        Func<View, int> f1 = _ => 0;
+        Func<View, int> f2 = _ => 0;
 
         Dim dim1 = Func (f1);
         Dim dim2 = Func (f1);
@@ -20,7 +20,7 @@ public class DimFuncTests (ITestOutputHelper output)
         dim2 = Func (f2);
         Assert.NotEqual (dim1, dim2);
 
-        f2 = () => 1;
+        f2 = _ => 1;
         dim2 = Func (f2);
         Assert.NotEqual (dim1, dim2);
     }
@@ -29,7 +29,7 @@ public class DimFuncTests (ITestOutputHelper output)
     public void DimFunc_SetsValue ()
     {
         var text = "Test";
-        Dim dim = Func (() => text.Length);
+        Dim dim = Func (_ => text.Length);
         Assert.Equal ("DimFunc(4)", dim.ToString ());
 
         text = "New Test";
@@ -42,8 +42,51 @@ public class DimFuncTests (ITestOutputHelper output)
     [Fact]
     public void DimFunc_Calculate_ReturnsCorrectValue ()
     {
-        var dim = new DimFunc (() => 10);
+        var dim = new DimFunc (_ => 10);
         int result = dim.Calculate (0, 100, null, Dimension.None);
         Assert.Equal (10, result);
     }
+
+    [Fact]
+    public void DimFunc_View_Equal ()
+    {
+        Func<View, int> f1 = v => v.Frame.Width;
+        Func<View, int> f2 = v => v.Frame.Width;
+        View view1 = new ();
+        View view2 = new ();
+
+        Dim dim1 = Func (f1, view1);
+        Dim dim2 = Func (f1, view1);
+        Assert.Equal (dim1, dim2);
+
+        dim2 = Func (f2, view2);
+        Assert.NotEqual (dim1, dim2);
+
+        view2.Width = 1;
+        Assert.NotEqual (dim1, dim2);
+        Assert.Equal (1, f2 (view2));
+    }
+
+    [Fact]
+    public void DimFunc_View_SetsValue ()
+    {
+        View view = new () { Text = "Test" };
+        Dim dim = Func (v => v.Text.Length, view);
+        Assert.Equal ("DimFunc(4)", dim.ToString ());
+
+        view.Text = "New Test";
+        Assert.Equal ("DimFunc(8)", dim.ToString ());
+
+        view.Text = "";
+        Assert.Equal ("DimFunc(0)", dim.ToString ());
+    }
+
+    [Fact]
+    public void DimFunc_View_Calculate_ReturnsCorrectValue ()
+    {
+        View view = new () { Width = 10 };
+        var dim = new DimFunc (v => v.Frame.Width, view);
+        int result = dim.Calculate (0, 100, view, Dimension.None);
+        Assert.Equal (10, result);
+    }
 }

+ 8 - 8
Tests/UnitTestsParallelizable/View/Layout/FrameTests.cs

@@ -61,10 +61,10 @@ public class FrameTests
         Assert.Equal (view.Height, frame.Height);
 
         // Set back to original state
-        view.X = Pos.Func (() => 10);
-        view.Y = Pos.Func (() => 20);
-        view.Width = Dim.Func (() => 30);
-        view.Height = Dim.Func (() => 40);
+        view.X = Pos.Func (_ => 10);
+        view.Y = Pos.Func (_ => 20);
+        view.Width = Dim.Func (_ => 30);
+        view.Height = Dim.Func (_ => 40);
         Assert.True (view.NeedsLayout);
 
         view.Layout ();
@@ -281,10 +281,10 @@ public class FrameTests
     {
         public FrameTestView ()
         {
-            X = Pos.Func (() => 10);
-            Y = Pos.Func (() => 20);
-            Width = Dim.Func (() => 30);
-            Height = Dim.Func (() => 40);
+            X = Pos.Func (_ => 10);
+            Y = Pos.Func (_ => 20);
+            Width = Dim.Func (_ => 30);
+            Height = Dim.Func (_ => 40);
         }
     }
 

+ 49 - 5
Tests/UnitTestsParallelizable/View/Layout/Pos.FuncTests.cs

@@ -9,14 +9,14 @@ public class PosFuncTests (ITestOutputHelper output)
     [Fact]
     public void PosFunc_Equal ()
     {
-        Func<int> f1 = () => 0;
-        Func<int> f2 = () => 0;
+        Func<View, int> f1 = _ => 0;
+        Func<View, int> f2 = _ => 0;
 
         Pos pos1 = Pos.Func (f1);
         Pos pos2 = Pos.Func (f1);
         Assert.Equal (pos1, pos2);
 
-        f2 = () => 1;
+        f2 = _ => 1;
         pos2 = Pos.Func (f2);
         Assert.NotEqual (pos1, pos2);
     }
@@ -25,7 +25,7 @@ public class PosFuncTests (ITestOutputHelper output)
     public void PosFunc_SetsValue ()
     {
         var text = "Test";
-        Pos pos = Pos.Func (() => text.Length);
+        Pos pos = Pos.Func (_ => text.Length);
         Assert.Equal ("PosFunc(4)", pos.ToString ());
 
         text = "New Test";
@@ -38,8 +38,52 @@ public class PosFuncTests (ITestOutputHelper output)
     [Fact]
     public void PosFunc_Calculate_ReturnsCorrectValue ()
     {
-        var pos = new PosFunc (() => 10);
+        var pos = new PosFunc (_ => 10);
         int result = pos.Calculate (0, 100, null, Dimension.None);
         Assert.Equal (10, result);
     }
+
+    [Fact]
+    public void PosFunc_View_Equal ()
+    {
+        Func<View, int> f1 = v => v.Frame.X;
+        Func<View, int> f2 = v => v.Frame.X;
+        View view1 = new ();
+        View view2 = new ();
+
+        Pos pos1 = Pos.Func (f1, view1);
+        Pos pos2 = Pos.Func (f1, view1);
+        Assert.Equal (pos1, pos2);
+
+        f2 = _ => 1;
+        pos2 = Pos.Func (f2, view2);
+        Assert.NotEqual (pos1, pos2);
+
+        view2.X = 1;
+        Assert.NotEqual (pos1, pos2);
+        Assert.Equal (1, f2 (view2));
+    }
+
+    [Fact]
+    public void PosFunc_View_SetsValue ()
+    {
+        View view = new () { Text = "Test" };
+        Pos pos = Pos.Func (v => v.Text.Length, view);
+        Assert.Equal ("PosFunc(4)", pos.ToString ());
+
+        view.Text = "New Test";
+        Assert.Equal ("PosFunc(8)", pos.ToString ());
+
+        view.Text = "";
+        Assert.Equal ("PosFunc(0)", pos.ToString ());
+    }
+
+    [Fact]
+    public void PosFunc_View_Calculate_ReturnsCorrectValue ()
+    {
+        View view = new () { X = 10 };
+        var pos = new PosFunc (v => v.Frame.X, view);
+        int result = pos.Calculate (0, 100, view, Dimension.None);
+        Assert.Equal (10, result);
+    }
 }

+ 2 - 2
Tests/UnitTestsParallelizable/View/Layout/Pos.Tests.cs

@@ -21,7 +21,7 @@ public class PosTests
     [Fact]
     public void PosFunc_Calculate_ReturnsExpectedValue ()
     {
-        var posFunc = new PosFunc (() => 5);
+        var posFunc = new PosFunc (_ => 5);
         int result = posFunc.Calculate (10, new DimAbsolute (2), null, Dimension.None);
         Assert.Equal (5, result);
     }
@@ -86,7 +86,7 @@ public class PosTests
     public void PosFunction_SetsValue ()
     {
         var text = "Test";
-        Pos pos = Pos.Func (() => text.Length);
+        Pos pos = Pos.Func (_ => text.Length);
         Assert.Equal ("PosFunc(4)", pos.ToString ());
 
         text = "New Test";

+ 4 - 4
Tests/UnitTestsParallelizable/View/Layout/SetLayoutTests.cs

@@ -597,7 +597,7 @@ public class SetLayoutTests : GlobalTestSetup
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.Height);
 
-        v.Height = Dim.Func (() => 10);
+        v.Height = Dim.Func (_ => 10);
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.Height);
 
@@ -649,7 +649,7 @@ public class SetLayoutTests : GlobalTestSetup
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.Width);
 
-        v.Width = Dim.Func (() => 10);
+        v.Width = Dim.Func (_ => 10);
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.Width);
 
@@ -675,7 +675,7 @@ public class SetLayoutTests : GlobalTestSetup
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.X);
 
-        v.X = Pos.Func (() => 10);
+        v.X = Pos.Func (_ => 10);
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.X);
 
@@ -731,7 +731,7 @@ public class SetLayoutTests : GlobalTestSetup
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.Y);
 
-        v.Y = Pos.Func (() => 10);
+        v.Y = Pos.Func (_ => 10);
         Assert.True (v.NeedsLayout);
         Assert.Equal (0, v.Frame.Y);
 

+ 3 - 2
Tests/UnitTestsParallelizable/View/Layout/SetRelativeLayoutTests.cs

@@ -1,4 +1,5 @@
-using UnitTests;
+using JetBrains.Annotations;
+using UnitTests;
 using Xunit.Abstractions;
 using static Terminal.Gui.ViewBase.Dim;
 
@@ -403,7 +404,7 @@ public class SetRelativeLayoutTests
         };
         view.X = Pos.AnchorEnd (0) - Pos.Func (GetViewWidth);
 
-        int GetViewWidth () { return view.Frame.Width; }
+        int GetViewWidth ([CanBeNull] View _) { return view.Frame.Width; }
 
         // view will be 3 chars wide. It's X will be 27 (30 - 3).
         // BUGBUG: IsInitialized need to be true before calculate