Browse Source

Merge branch 'develop'

Tig 1 year ago
parent
commit
d774f622a1

+ 1 - 1
.github/workflows/api-docs.yml

@@ -31,7 +31,7 @@ jobs:
       continue-on-error: false
       continue-on-error: false
 
 
     - name: Setup Pages
     - name: Setup Pages
-      uses: actions/configure-pages@v4
+      uses: actions/configure-pages@v5
       
       
     - name: Upload artifact
     - name: Upload artifact
       uses: actions/upload-pages-artifact@v2
       uses: actions/upload-pages-artifact@v2

+ 3 - 3
.github/workflows/publish.yml

@@ -19,13 +19,13 @@ jobs:
         fetch-depth: 0 # fetch-depth is needed for GitVersion
         fetch-depth: 0 # fetch-depth is needed for GitVersion
 
 
     - name: Install GitVersion 
     - name: Install GitVersion 
-      uses: gittools/actions/gitversion/setup@v0
+      uses: gittools/actions/gitversion/setup@v1
       with:
       with:
           versionSpec: '5.x'
           versionSpec: '5.x'
           includePrerelease: true
           includePrerelease: true
 
 
     - name: Determine Version
     - name: Determine Version
-      uses: gittools/actions/gitversion/execute@v0
+      uses: gittools/actions/gitversion/execute@v1
       with:
       with:
         useConfigFile: true
         useConfigFile: true
         #additionalArguments: /b develop
         #additionalArguments: /b develop
@@ -34,7 +34,7 @@ jobs:
     - name: Setup dotnet
     - name: Setup dotnet
       uses: actions/setup-dotnet@v4
       uses: actions/setup-dotnet@v4
       with:
       with:
-        dotnet-version: 7.0
+        dotnet-version: 8.0
         dotnet-quality: 'ga'
         dotnet-quality: 'ga'
         
         
     - name: Install dependencies
     - name: Install dependencies

+ 1 - 1
Example/Example.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <OutputType>Exe</OutputType>
-    <TargetFramework>net7.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <!-- Version numbers are automatically updated by gitversion when a release is released -->
     <!-- Version numbers are automatically updated by gitversion when a release is released -->
     <!-- Do not modify these. -->
     <!-- Do not modify these. -->
     <FileVersion>1.0.0.0</FileVersion>
     <FileVersion>1.0.0.0</FileVersion>

+ 1 - 1
README.md

@@ -40,7 +40,7 @@ dotnet run
 
 
 _The Documentation matches the most recent Nuget release from the `main` branch ([![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui))_
 _The Documentation matches the most recent Nuget release from the `main` branch ([![Version](https://img.shields.io/nuget/v/Terminal.Gui.svg)](https://www.nuget.org/packages/Terminal.Gui))_
 
 
-See the [`Terminal.Gui/` README](https://github.com/gui-cs/Terminal.Gui/tree/master/Terminal.Gui) for an overview of how the library is structured. The [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/articles/index.html) provides insight into core concepts.
+See the [`Terminal.Gui/` README](https://github.com/gui-cs/Terminal.Gui/tree/master/Terminal.Gui) for an overview of how the library is structured. The [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/docs/index.html) provides insight into core concepts.
 
 
 ## Features
 ## Features
 
 

+ 2 - 2
ReactiveExample/ReactiveExample.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <OutputType>Exe</OutputType>
-    <TargetFramework>net7.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <!-- Version numbers are automatically updated by gitversion when a release is released -->
     <!-- Version numbers are automatically updated by gitversion when a release is released -->
     <!-- Do not modify these. -->
     <!-- Do not modify these. -->
     <!--<AssemblyVersion>1.14.0.0</AssemblyVersion>
     <!--<AssemblyVersion>1.14.0.0</AssemblyVersion>
@@ -11,7 +11,7 @@
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
     <PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
-    <PackageReference Include="ReactiveUI" Version="19.5.41" />
+    <PackageReference Include="ReactiveUI" Version="20.1.1" />
     <PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
     <PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>

+ 6 - 2
Showcase.md

@@ -16,10 +16,14 @@
   ![PoshDotnetDumpAnalyzerViewer.png](docfx/images/PoshDotnetDumpAnalyzerViewer.png)  
   ![PoshDotnetDumpAnalyzerViewer.png](docfx/images/PoshDotnetDumpAnalyzerViewer.png)  
 * **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications.
 * **[TerminalGuiDesigner](https://github.com/tznind/TerminalGuiDesigner)** - Cross platform view designer for building Terminal.Gui applications.
-  ![TerminalGuiDesigner.gif](docfx/images/TerminalGuiDesigner.gif)  
+  ![TerminalGuiDesigner.gif](docfx/images/TerminalGuiDesigner.gif)
+
+* **[Capital and Cargo](https://github.com/dhorions/Capital-and-Cargo)** - A retro console game where you buy, sell, produce and transport goods built with Terminal.Gui
+ ![image](https://github.com/gui-cs/Terminal.Gui/assets/1682004/ed89f3d6-020f-4a8a-ae18-e057514f4c43)
+
   
   
 # Examples #
 # Examples #
 
 
 * **[C# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/Example)** - Run `dotnet run` in the `Example` directory to run the C# Example.
 * **[C# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/Example)** - Run `dotnet run` in the `Example` directory to run the C# Example.
 * **[F# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/FSharpExample)** - An example showing how to build a Terminal.Gui app using F#.
 * **[F# Example](https://github.com/gui-cs/Terminal.Gui/tree/master/FSharpExample)** - An example showing how to build a Terminal.Gui app using F#.
-* **[Reactive Example](https://github.com/gui-cs/Terminal.Gui/tree/master/ReactiveExample)** - A sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers. 
+* **[Reactive Example](https://github.com/gui-cs/Terminal.Gui/tree/master/ReactiveExample)** - A sample app that shows how to use `System.Reactive` and `ReactiveUI` with `Terminal.Gui`. The app uses the MVVM architecture that may seem familiar to folks coming from WPF, Xamarin Forms, UWP, Avalonia, or Windows Forms. In this app, we implement the data bindings using ReactiveUI `WhenAnyValue` syntax and [Pharmacist](https://github.com/reactiveui/pharmacist) — a tool that converts all events in a NuGet package into observable wrappers. 

+ 1 - 0
Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs

@@ -505,6 +505,7 @@ namespace Terminal.Gui {
 					keyHandler (key);
 					keyHandler (key);
 				} else {
 				} else {
 					k = Key.Esc;
 					k = Key.Esc;
+					keyDownHandler (new KeyEvent (k, MapKeyModifiers (k)));
 					keyHandler (new KeyEvent (k, MapKeyModifiers (k)));
 					keyHandler (new KeyEvent (k, MapKeyModifiers (k)));
 				}
 				}
 			} else if (wch == Curses.KeyTab) {
 			} else if (wch == Curses.KeyTab) {

+ 1 - 3
Terminal.Gui/Core/Application.cs

@@ -1040,9 +1040,7 @@ namespace Terminal.Gui {
 			if (refreshDriver) {
 			if (refreshDriver) {
 				MdiTop?.OnChildLoaded (toplevel);
 				MdiTop?.OnChildLoaded (toplevel);
 				toplevel.OnLoaded ();
 				toplevel.OnLoaded ();
-				Redraw (toplevel);
-				toplevel.PositionCursor ();
-				Driver.Refresh ();
+				Refresh ();
 			}
 			}
 
 
 			NotifyNewRunState?.Invoke (rs);
 			NotifyNewRunState?.Invoke (rs);

+ 2 - 2
Terminal.Gui/Core/Clipboard/Clipboard.cs

@@ -51,8 +51,8 @@ namespace Terminal.Gui {
 						Application.Driver.Clipboard.SetClipboardData (value.ToString ());
 						Application.Driver.Clipboard.SetClipboardData (value.ToString ());
 					}
 					}
 					contents = value;
 					contents = value;
-				} catch (NotSupportedException e) {
-					throw e;
+				} catch (NotSupportedException) {
+					throw;
 				} catch (Exception) {
 				} catch (Exception) {
 					contents = value;
 					contents = value;
 				}
 				}

+ 4 - 4
Terminal.Gui/Core/Event.cs

@@ -753,13 +753,13 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// </summary>
 		WheeledDown = unchecked((int)0x20000000),
 		WheeledDown = unchecked((int)0x20000000),
 		/// <summary>
 		/// <summary>
-		/// Vertical button wheeled up while pressing ButtonShift.
+		/// Vertical button wheeled up while pressing ButtonCtrl.
 		/// </summary>
 		/// </summary>
-		WheeledLeft = ButtonShift | WheeledUp,
+		WheeledLeft = ButtonCtrl | WheeledUp,
 		/// <summary>
 		/// <summary>
-		/// Vertical button wheeled down while pressing ButtonShift.
+		/// Vertical button wheeled down while pressing ButtonCtrl.
 		/// </summary>
 		/// </summary>
-		WheeledRight = ButtonShift | WheeledDown,
+		WheeledRight = ButtonCtrl | WheeledDown,
 		/// <summary>
 		/// <summary>
 		/// Mask that captures all the events.
 		/// Mask that captures all the events.
 		/// </summary>
 		/// </summary>

+ 1 - 1
Terminal.Gui/Core/View.cs

@@ -282,7 +282,7 @@ namespace Terminal.Gui {
 				} else if (SuperView?.tabIndexes == null || SuperView?.tabIndexes.Count == 1) {
 				} else if (SuperView?.tabIndexes == null || SuperView?.tabIndexes.Count == 1) {
 					tabIndex = 0;
 					tabIndex = 0;
 					return;
 					return;
-				} else if (tabIndex == value) {
+				} else if (tabIndex == value && TabIndexes.IndexOf (this) == value) {
 					return;
 					return;
 				}
 				}
 				tabIndex = value > SuperView.tabIndexes.Count - 1 ? SuperView.tabIndexes.Count - 1 : value < 0 ? 0 : value;
 				tabIndex = value > SuperView.tabIndexes.Count - 1 ? SuperView.tabIndexes.Count - 1 : value < 0 ? 0 : value;

+ 1 - 1
Terminal.Gui/Terminal.Gui.csproj

@@ -20,7 +20,7 @@
     <DebugType>portable</DebugType>
     <DebugType>portable</DebugType>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup>
   <PropertyGroup>
-    <TargetFrameworks>net472;netstandard2.1;net7.0</TargetFrameworks>
+    <TargetFrameworks>net472;netstandard2.0;netstandard2.1;net7.0;net8.0</TargetFrameworks>
     <RootNamespace>Terminal.Gui</RootNamespace>
     <RootNamespace>Terminal.Gui</RootNamespace>
     <AssemblyName>Terminal.Gui</AssemblyName>
     <AssemblyName>Terminal.Gui</AssemblyName>
     <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
     <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>

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

@@ -792,7 +792,7 @@ namespace Terminal.Gui {
 			listview.SetSource (searchset);
 			listview.SetSource (searchset);
 			listview.Height = CalculatetHeight ();
 			listview.Height = CalculatetHeight ();
 
 
-			if (Subviews.Count > 0) {
+			if (HasFocus && Subviews.Count > 0) {
 				search.SetFocus ();
 				search.SetFocus ();
 			}
 			}
 		}
 		}

+ 3 - 2
Terminal.Gui/Views/ListView.cs

@@ -864,7 +864,8 @@ namespace Terminal.Gui {
 
 
 		void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width, int start = 0)
 		void RenderUstr (ConsoleDriver driver, ustring ustr, int col, int line, int width, int start = 0)
 		{
 		{
-			var u = TextFormatter.ClipAndJustify (ustr, width + start, TextAlignment.Left);
+			ustring str = start > ustr.ConsoleWidth ? string.Empty : ustr.Substring (Math.Min (start, ustr.ToRunes ().Length - 1));
+			ustring u = TextFormatter.ClipAndJustify (str, width, TextAlignment.Left);
 			driver.AddStr (u);
 			driver.AddStr (u);
 			width -= TextFormatter.GetTextWidth (u);
 			width -= TextFormatter.GetTextWidth (u);
 			while (width-- + start > 0) {
 			while (width-- + start > 0) {
@@ -876,7 +877,7 @@ namespace Terminal.Gui {
 		public void Render (ListView container, ConsoleDriver driver, bool marked, int item, int col, int line, int width, int start = 0)
 		public void Render (ListView container, ConsoleDriver driver, bool marked, int item, int col, int line, int width, int start = 0)
 		{
 		{
 			var savedClip = container.ClipToBounds ();
 			var savedClip = container.ClipToBounds ();
-			container.Move (col - start, line);
+			container.Move (Math.Max (col - start, 0), line);
 			var t = src? [item];
 			var t = src? [item];
 			if (t == null) {
 			if (t == null) {
 				RenderUstr (driver, ustring.Make (""), col, line, width);
 				RenderUstr (driver, ustring.Make (""), col, line, width);

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

@@ -349,7 +349,7 @@ namespace Terminal.Gui {
 		{
 		{
 			Driver.SetAttribute (GetNormalColor ());
 			Driver.SetAttribute (GetNormalColor ());
 			SetViewsNeedsDisplay ();
 			SetViewsNeedsDisplay ();
-			//Clear ();
+			Clear ();
 
 
 			var savedClip = ClipToBounds ();
 			var savedClip = ClipToBounds ();
 			OnDrawContent (new Rect (ContentOffset,
 			OnDrawContent (new Rect (ContentOffset,

+ 4 - 0
Terminal.Gui/Windows/Wizard.cs

@@ -773,6 +773,10 @@ namespace Terminal.Gui {
 			var oldStep = currentStep;
 			var oldStep = currentStep;
 			currentStep = newStep;
 			currentStep = newStep;
 
 
+			if (currentStep is null) {
+				return false;
+			}
+
 			UpdateButtonsAndTitle ();
 			UpdateButtonsAndTitle ();
 
 
 			// Set focus to the nav buttons
 			// Set focus to the nav buttons

+ 5 - 1
Terminal.sln.DotSettings

@@ -112,6 +112,9 @@
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=Constants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateInstanceFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
 	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
+	<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
 	<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=CAF4ECB3AC41AE43BD233D613AC1562C/@KeyIndexDefined">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=CAF4ECB3AC41AE43BD233D613AC1562C/@KeyIndexDefined">True</s:Boolean>
 	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=CAF4ECB3AC41AE43BD233D613AC1562C/AbsolutePath/@EntryValue">Terminal.sln.DotSettings</s:String>
 	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=CAF4ECB3AC41AE43BD233D613AC1562C/AbsolutePath/@EntryValue">Terminal.sln.DotSettings</s:String>
 	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=CAF4ECB3AC41AE43BD233D613AC1562C/RelativePath/@EntryValue"></s:String>
 	<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=CAF4ECB3AC41AE43BD233D613AC1562C/RelativePath/@EntryValue"></s:String>
@@ -125,4 +128,5 @@
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
 	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
+	<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 1 - 1
UICatalog/Dockerfile

@@ -16,7 +16,7 @@ ENV LANG=en_US.UTF-8 \
 	DISPLAY=:0
 	DISPLAY=:0
 WORKDIR /app
 WORKDIR /app
 
 
-FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
 WORKDIR /src
 WORKDIR /src
 COPY ["Terminal.Gui/Directory.Build.props", "Terminal.Gui/"]
 COPY ["Terminal.Gui/Directory.Build.props", "Terminal.Gui/"]
 COPY ["UICatalog/UICatalog.csproj", "UICatalog/"]
 COPY ["UICatalog/UICatalog.csproj", "UICatalog/"]

+ 2 - 2
UICatalog/Scenarios/ListViewWithSelection.cs

@@ -79,9 +79,9 @@ namespace UICatalog.Scenarios {
 			};
 			};
 
 
 			_listView.DrawContent += (e) => {
 			_listView.DrawContent += (e) => {
-				_scrollBar.Size = _listView.Source.Count - 1;
+				_scrollBar.Size = _listView.Source.Count;
 				_scrollBar.Position = _listView.TopItem;
 				_scrollBar.Position = _listView.TopItem;
-				_scrollBar.OtherScrollBarView.Size = _listView.Maxlength - 1;
+				_scrollBar.OtherScrollBarView.Size = _listView.Maxlength;
 				_scrollBar.OtherScrollBarView.Position = _listView.LeftItem;
 				_scrollBar.OtherScrollBarView.Position = _listView.LeftItem;
 				_scrollBar.Refresh ();
 				_scrollBar.Refresh ();
 			};
 			};

+ 4 - 4
UICatalog/UICatalog.csproj

@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
     <OutputType>Exe</OutputType>
     <OutputType>Exe</OutputType>
-    <TargetFramework>net7.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <LangVersion>9.0</LangVersion>
     <LangVersion>9.0</LangVersion>
     <StartupObject>UICatalog.UICatalogApp</StartupObject>
     <StartupObject>UICatalog.UICatalogApp</StartupObject>
     <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
     <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
@@ -20,9 +20,9 @@
     <None Update="./Scenarios/Spinning_globe_dark_small.gif" CopyToOutputDirectory="PreserveNewest" />
     <None Update="./Scenarios/Spinning_globe_dark_small.gif" CopyToOutputDirectory="PreserveNewest" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
-    <PackageReference Include="SixLabors.ImageSharp" Version="3.1.2" />
-    <PackageReference Include="CsvHelper" Version="31.0.0" />
+    <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
+    <PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
+    <PackageReference Include="CsvHelper" Version="32.0.3" />
     <PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
     <PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>

+ 6 - 6
UnitTests/UnitTests.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
   <PropertyGroup>
-    <TargetFramework>net7.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
     <!-- https://stackoverflow.com/questions/294216/why-does-c-sharp-forbid-generic-attribute-types -->
     <!-- https://stackoverflow.com/questions/294216/why-does-c-sharp-forbid-generic-attribute-types -->
     <!-- for AutoInitShutdown attribute -->
     <!-- for AutoInitShutdown attribute -->
     <LangVersion>Preview</LangVersion>
     <LangVersion>Preview</LangVersion>
@@ -18,15 +18,15 @@
     <DefineConstants>TRACE;DEBUG_IDISPOSABLE</DefineConstants>
     <DefineConstants>TRACE;DEBUG_IDISPOSABLE</DefineConstants>
   </PropertyGroup>
   </PropertyGroup>
   <ItemGroup>
   <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
-    <PackageReference Include="ReportGenerator" Version="5.2.2" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
+    <PackageReference Include="ReportGenerator" Version="5.3.4" />
     <PackageReference Include="System.Collections" Version="4.3.0" />
     <PackageReference Include="System.Collections" Version="4.3.0" />
-    <PackageReference Include="xunit" Version="2.7.0" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
+    <PackageReference Include="xunit" Version="2.8.1" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
       <PrivateAssets>all</PrivateAssets>
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
     </PackageReference>
-    <PackageReference Include="coverlet.collector" Version="6.0.1">
+    <PackageReference Include="coverlet.collector" Version="6.0.2">
       <PrivateAssets>all</PrivateAssets>
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
     </PackageReference>

+ 77 - 0
UnitTests/Views/ViewTests.cs

@@ -371,6 +371,79 @@ namespace Terminal.Gui.ViewTests {
 			Assert.True (r.TabIndexes.IndexOf (v1) == 1);
 			Assert.True (r.TabIndexes.IndexOf (v1) == 1);
 		}
 		}
 
 
+		[Fact]
+		public void TabIndex_Invert_Order ()
+		{
+			var r = new View ();
+			var v1 = new View () { Id = "1", CanFocus = true };
+			var v2 = new View () { Id = "2", CanFocus = true };
+			var v3 = new View () { Id = "3", CanFocus = true };
+
+			r.Add (v1, v2, v3);
+
+			v1.TabIndex = 2;
+			v2.TabIndex = 1;
+			v3.TabIndex = 0;
+			Assert.True (r.TabIndexes.IndexOf (v1) == 2);
+			Assert.True (r.TabIndexes.IndexOf (v2) == 1);
+			Assert.True (r.TabIndexes.IndexOf (v3) == 0);
+
+			Assert.True (r.Subviews.IndexOf (v1) == 0);
+			Assert.True (r.Subviews.IndexOf (v2) == 1);
+			Assert.True (r.Subviews.IndexOf (v3) == 2);
+		}
+
+		[Fact]
+		public void TabIndex_Invert_Order_Added_One_By_One_Does_Not_Do_What_Is_Expected ()
+		{
+			var r = new View ();
+			var v1 = new View () { Id = "1", CanFocus = true };
+			r.Add (v1);
+			v1.TabIndex = 2;
+			var v2 = new View () { Id = "2", CanFocus = true };
+			r.Add (v2);
+			v2.TabIndex = 1;
+			var v3 = new View () { Id = "3", CanFocus = true };
+			r.Add (v3);
+			v3.TabIndex = 0;
+
+			Assert.False (r.TabIndexes.IndexOf (v1) == 2);
+			Assert.True (r.TabIndexes.IndexOf (v1) == 1);
+			Assert.False (r.TabIndexes.IndexOf (v2) == 1);
+			Assert.True (r.TabIndexes.IndexOf (v2) == 2);
+			// Only the last is in the expected index
+			Assert.True (r.TabIndexes.IndexOf (v3) == 0);
+
+			Assert.True (r.Subviews.IndexOf (v1) == 0);
+			Assert.True (r.Subviews.IndexOf (v2) == 1);
+			Assert.True (r.Subviews.IndexOf (v3) == 2);
+		}
+
+		[Fact]
+		public void TabIndex_Invert_Order_Mixed ()
+		{
+			var r = new View ();
+			var vl1 = new View () { Id = "vl1" };
+			var v1 = new View () { Id = "v1", CanFocus = true };
+			var vl2 = new View () { Id = "vl2" };
+			var v2 = new View () { Id = "v2", CanFocus = true };
+			var vl3 = new View () { Id = "vl3" };
+			var v3 = new View () { Id = "v3", CanFocus = true };
+
+			r.Add (vl1, v1, vl2, v2, vl3, v3);
+
+			v1.TabIndex = 2;
+			v2.TabIndex = 1;
+			v3.TabIndex = 0;
+			Assert.True (r.TabIndexes.IndexOf (v1) == 4);
+			Assert.True (r.TabIndexes.IndexOf (v2) == 2);
+			Assert.True (r.TabIndexes.IndexOf (v3) == 0);
+
+			Assert.True (r.Subviews.IndexOf (v1) == 1);
+			Assert.True (r.Subviews.IndexOf (v2) == 3);
+			Assert.True (r.Subviews.IndexOf (v3) == 5);
+		}
+
 		[Fact]
 		[Fact]
 		public void TabStop_And_CanFocus_Are_All_True ()
 		public void TabStop_And_CanFocus_Are_All_True ()
 		{
 		{
@@ -1173,6 +1246,10 @@ namespace Terminal.Gui.ViewTests {
 
 
 			Application.Run ();
 			Application.Run ();
 
 
+			// Ensures cleaning any keystroke.
+			// This was conflicting with the TestVKPacket unit test
+			Console.MockKeyPresses.Clear ();
+
 			// Shutdown must be called to safely clean up Application if Init has been called
 			// Shutdown must be called to safely clean up Application if Init has been called
 			Application.Shutdown ();
 			Application.Shutdown ();
 		}
 		}

+ 1 - 1
global.json

@@ -1,6 +1,6 @@
 {
 {
   "sdk":{
   "sdk":{
-    "version":"7.0.200",
+    "version":"8.0.204",
     "rollForward":"latestMinor"
     "rollForward":"latestMinor"
   }
   }
 }
 }