Explorar o código

Merge branch 'v1_release' of github.com:gui-cs/Terminal.Gui into v1_release

Tig hai 3 meses
pai
achega
ad6f97c901

+ 18 - 10
.github/workflows/dotnet-core.yml

@@ -9,32 +9,40 @@ on:
     branches: [ v1_release, v1_develop ]
     paths-ignore:
       - '**.md'
-      
 jobs:
-  build:
-    runs-on: ubuntu-latest
+  non_parallel_unittests:
+    name: Non-Parallel Unit Tests  
+    runs-on: ${{ matrix.os }}
+    strategy:
+      # Turn off fail-fast to let all runners run even if there are errors
+      fail-fast: true
+      matrix:
+        os: [ ubuntu-latest ]
+
     timeout-minutes: 10
     steps:
-    - uses: actions/checkout@v4
+
+    - name: Checkout code
+      uses: actions/checkout@v4
 
     - name: Setup .NET Core
       uses: actions/setup-dotnet@v4
       with:
-        dotnet-version: 7.0
+        dotnet-version: 8.x
         dotnet-quality: 'ga'
 
     - name: Install dependencies
       run: |
         dotnet restore
 
-    - name: Build Debug
-      run: |
-        dotnet build --configuration Debug --no-restore
+    - name: Build Solution Debug
+      run: dotnet build --configuration Debug --no-restore
         
     - name: Test
       run: |
-        sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
-        dotnet test --no-restore --verbosity normal #--collect:"XPlat Code Coverage"  --settings UnitTests/coverlet.runsettings
+        #sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
+        dotnet test --no-restore --verbosity normal 
+        #--collect:"XPlat Code Coverage"  --settings UnitTests/coverlet.runsettings
         #mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
 
     # Note: this step is currently not writing to the gist for some reason

+ 17 - 18
.github/workflows/publish.yml

@@ -1,8 +1,8 @@
-name: Publish Terminal.Gui
+name: Publish Terminal.Gui v1
 
 on:
   push:
-    branches: [ v1_release, v1_develop, v2_release, v2_develop ]
+    branches: [ v1_release, v1_develop ]
     tags:
       - v*
     paths-ignore:
@@ -18,35 +18,34 @@ jobs:
       with:
         fetch-depth: 0 # fetch-depth is needed for GitVersion
 
-    - name: Install GitVersion 
-      uses: gittools/actions/gitversion/setup@v1
+    - name: Setup .NET Core
+      uses: actions/setup-dotnet@v4
+      with:
+        dotnet-version: 8.x
+        dotnet-quality: 'ga'
+
+    - name: Install GitVersion
+      uses: gittools/actions/gitversion/[email protected]
       with:
-          versionSpec: '5.x'
-          includePrerelease: true
+        versionSpec: '6.0.x'
 
     - name: Determine Version
-      uses: gittools/actions/gitversion/execute@v1
+      uses: gittools/actions/gitversion/execute@v3.1.11
       with:
         useConfigFile: true
-        #additionalArguments: /b develop
+        updateAssemblyInfo: true
       id: gitversion # step id used as reference for output values
 
-    - name: Setup dotnet
-      uses: actions/setup-dotnet@v4
-      with:
-        dotnet-version: 8.0
-        dotnet-quality: 'ga'
-        
     - name: Install dependencies
       run: dotnet restore
 
     - name: Build Release
       run: |
-        dotnet-gitversion /updateprojectfiles
-        dotnet build --no-restore -c Release
+        dotnet build Terminal.Gui/Terminal.Gui.csproj --no-incremental --nologo --force --configuration Release
+        dotnet test Terminal.Gui/Terminal.Gui.csproj --configuration Release
 
     - name: Pack
-      run: dotnet pack -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}' 
+      run: dotnet pack Terminal.Gui/Terminal.Gui.csproj -c Release --include-symbols -p:Version='${{ steps.gitversion.outputs.SemVer }}' 
 
     # - name: Test to generate Code Coverage Report
     #   run: |
@@ -71,4 +70,4 @@ jobs:
     #     echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"
         
     - name: Publish to NuGet.org
-      run: dotnet nuget push Terminal.Gui/bin/Release/Terminal.Gui.${{ steps.gitversion.outputs.SemVer }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }} 
+      run: dotnet nuget push Terminal.Gui/bin/Release/Terminal.Gui.${{ steps.gitversion.outputs.SemVer }}.nupkg --api-key ${{ secrets.NUGET_API_KEY }} 

+ 56 - 10
.gitignore

@@ -1,24 +1,70 @@
-bin
-obj
-~$*
+# Build artifacts
+[Bb]in/
+[Oo]bj/
+[Rr]elease/
+[Dd]ebug/
+[Xx]64/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+
+# User-local settings and caches
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
 *.userprefs
+_ReSharper.**
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+.devcontainer/
+.vscode/
+.vs/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Roslyn generated cs files
+**.g.cs
+
+# Common temporary files
+~$*
 *~
-packages
-.vs
-# User-specific files
-*.user
+
+# Exclude everything in packages directory except the packages/build directory
+**/[Pp]ackages/*
+!**/[Pp]ackages/build/
 
 # API Docs
 docfx/api
 docfx/_site
 
+# Test Results
 UnitTests/TestResults
+TestResults
 
-#git merge files
+# git merge files
 *.orig
-
-.vscode/
+*.theirs
+*.ours
 
 demo.*
 
 *.deb
+
+*.tui/
+
+*.dotCover
+
+logs/
+
+BenchmarkDotNet.Artifacts/
+
+*.log
+
+*.log.*
+
+log.*

+ 80 - 23
GitVersion.yml

@@ -1,29 +1,86 @@
-mode: ContinuousDeployment
+# This file configures GitVersion 6.x to work with Terminal.Gui's GitFlow branching strategy.
+#
+# Terminal.Gui uses the GitFlow branching strategy.
+# https://gitversion.net/docs/learn/branching-strategies/gitflow/
+#
+# - We have two main branches: `v1_release` and `v1_develop`.
+# - `v1_release` is the main branch for V1 releases and matches the latest NuGet release package (e.g., 1.0.0);
+#   prior to release, it uses pre-release labels (e.g., 1.0.0-prealpha.1).
+# - `v1_develop` is the development branch for V2 and always carries a pre-release label (e.g., 1.1.0-develop.1).
+# - Development happens on feature branches off `v1_develop`.
+# - For releases, we merge feature branches into `v1_develop`, then `v1_develop` into `v1_release`.
+# - The ./.github/workflows/publish.yml builds and publishes on pushes to `v1_develop` and `v1_release`.
+#
+# Branches
+# - v1_release: Main branch for V1 (historical)
+# - v1_develop: Develop branch for V1 (historical)
+#
+# Package Naming:
+# - from v1_develop: 2.1.0-develop.1 (minor version increments)
+# - from v1_release (pre-release): 2.0.0-prealpha.1 or 2.0.0-beta.1
+# - from v1_release (release): 2.0.0 (patch version increments)
+#
+mode: ContinuousDelivery   # GitVersion 6.x uses Mainline mode for GitFlow, focusing on main branch releases
+
+# We prefix our tags with 'v' or 'V' (e.g., v1.0.0)
 tag-prefix: '[vV]'
-continuous-delivery-fallback-tag: pre
+
 branches:
-  v1_develop:
-    mode: ContinuousDeployment
-    tag: pre
-    regex: v1_develop
-    source-branches:
-    - v1_release
-    pre-release-weight: 100
-  v1_release:
-    tag: rc
+
+  # V2 Release Branch
+  main:
+    # Matches the v1_release branch
+    regex: ^v1_release$
+    # Increments patch version (x.y.z+1) on commits
     increment: Patch
-    regex: v1_release
-    source-branches:
-    - v1_develop
-    - v1_release
-  v1_feature:
-    tag: useBranchName
-    regex: ^features?[/-]
-    source-branches:
-    - v1_develop
-    - v1_release
+    # Specifies v1_develop as the source branch
+    source-branches: ['develop']
+    pre-release-weight: 100
+
+  # V2 Development Branch
+  develop:
+    # Matches the v1_develop branch
+    regex: v1_develop
+    # Adds 'develop' as pre-release label (e.g., 2.1.0-develop.1)
+    label: develop
+    # Increments minor version (x.y+1.z) on commits
+    increment: Minor
+    # No source branches specified as this is the root of development
+    source-branches: []
+    # Indicates this branch feeds into release branches
+    tracks-release-branches: true
+
+  # # V1 Branches - Included for historical reference
+  # v1_develop:
+  #   regex: v1_develop
+  #   label: v1_develop
+  #   increment: Minor
+  #   source-branches: ['v1_release']
+  #   # Lower weight keeps V1 pre-releases sorted below V2
+  #   pre-release-weight: 100
+
+  # v1_release:
+  #   regex: v1_release
+  #   # Empty label for stable releases
+  #   label: ''
+  #   increment: Patch
+  #   source-branches: ['v1_develop']
+
+  # Pull Request Branches
+  # Configures versioning for PRs (e.g., 2.0.0-pr.feature-123.1)
   pull-request:
-    tag: PullRequest.{BranchName}
+    # Matches typical PR branch names
+    regex: ^(pull|pull\-requests|pr)[/-]
+    # Uses 'pr' prefix with branch name in the label (e.g., pr.feature-123)
+    label: pr.{BranchName}
+    # Inherits increment strategy from source branch
     increment: Inherit
+    source-branches:
+      - develop
+      - main
+    # High weight ensures PR versions sort after regular pre-releases
+    pre-release-weight: 30000
+
+# Ignore specific commits if needed (currently empty)
 ignore:
-  sha: []
+  sha: []

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

@@ -97,7 +97,7 @@ namespace Terminal.Gui {
 			this.mainLoop = mainLoop;
 			pipe (wakeupPipes);
 			AddWatch (wakeupPipes [0], Condition.PollIn, ml => {
-				read (wakeupPipes [1], ignore, (IntPtr)1);
+				read (wakeupPipes [0], ignore, (IntPtr)1);
 				return true;
 			});
 		}

+ 148 - 127
Terminal.Gui/ConsoleDrivers/WindowsDriver.cs

@@ -18,7 +18,6 @@ namespace Terminal.Gui {
 		public const int STD_ERROR_HANDLE = -12;
 
 		internal IntPtr InputHandle, OutputHandle;
-		IntPtr ScreenBuffer;
 		readonly uint originalConsoleMode;
 		CursorVisibility? initialCursorVisibility = null;
 		CursorVisibility? currentCursorVisibility = null;
@@ -40,47 +39,47 @@ namespace Terminal.Gui {
 
 		public bool WriteToConsole (Size size, CharInfo [] charInfoBuffer, Coord coords, SmallRect window)
 		{
-			if (ScreenBuffer == IntPtr.Zero) {
-				ReadFromConsoleOutput (size, coords, ref window);
-			}
+			//if (OutputHandle == IntPtr.Zero) {
+			//	ReadFromConsoleOutput (size, coords, ref window);
+			//}
 
-			return WriteConsoleOutput (ScreenBuffer, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window);
+			return WriteConsoleOutput (OutputHandle, charInfoBuffer, coords, new Coord () { X = window.Left, Y = window.Top }, ref window);
 		}
 
-		public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
-		{
-			ScreenBuffer = CreateConsoleScreenBuffer (
-				DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
-				ShareMode.FileShareRead | ShareMode.FileShareWrite,
-				IntPtr.Zero,
-				1,
-				IntPtr.Zero
-			);
-			if (ScreenBuffer == INVALID_HANDLE_VALUE) {
-				var err = Marshal.GetLastWin32Error ();
+		//public void ReadFromConsoleOutput (Size size, Coord coords, ref SmallRect window)
+		//{
+		//	OutputHandle = CreateConsoleScreenBuffer (
+		//		DesiredAccess.GenericRead | DesiredAccess.GenericWrite,
+		//		ShareMode.FileShareRead | ShareMode.FileShareWrite,
+		//		IntPtr.Zero,
+		//		1,
+		//		IntPtr.Zero
+		//	);
+		//	if (ScreenBuffer == INVALID_HANDLE_VALUE) {
+		//		var err = Marshal.GetLastWin32Error ();
 
-				if (err != 0)
-					throw new System.ComponentModel.Win32Exception (err);
-			}
+		//		if (err != 0)
+		//			throw new System.ComponentModel.Win32Exception (err);
+		//	}
 
-			if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) {
-				initialCursorVisibility = visibility;
-			}
+		//	if (!initialCursorVisibility.HasValue && GetCursorVisibility (out CursorVisibility visibility)) {
+		//		initialCursorVisibility = visibility;
+		//	}
 
-			if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
+		//	if (!SetConsoleActiveScreenBuffer (ScreenBuffer)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
 
-			OriginalStdOutChars = new CharInfo [size.Height * size.Width];
+		//	OriginalStdOutChars = new CharInfo [size.Height * size.Width];
 
-			if (!ReadConsoleOutput (ScreenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-		}
+		//	if (!ReadConsoleOutput (ScreenBuffer, OriginalStdOutChars, coords, new Coord () { X = 0, Y = 0 }, ref window)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+		//}
 
 		public bool SetCursorPosition (Coord position)
 		{
-			return SetConsoleCursorPosition (ScreenBuffer, position);
+			return SetConsoleCursorPosition (OutputHandle, position);
 		}
 
 		public void SetInitialCursorVisibility ()
@@ -92,11 +91,11 @@ namespace Terminal.Gui {
 
 		public bool GetCursorVisibility (out CursorVisibility visibility)
 		{
-			if (ScreenBuffer == IntPtr.Zero) {
+			if (OutputHandle == IntPtr.Zero) {
 				visibility = CursorVisibility.Invisible;
 				return false;
 			}
-			if (!GetConsoleCursorInfo (ScreenBuffer, out ConsoleCursorInfo info)) {
+			if (!GetConsoleCursorInfo (OutputHandle, out ConsoleCursorInfo info)) {
 				var err = Marshal.GetLastWin32Error ();
 				if (err != 0) {
 					throw new System.ComponentModel.Win32Exception (err);
@@ -149,7 +148,7 @@ namespace Terminal.Gui {
 					bVisible = ((uint)visibility & 0xFF00) != 0
 				};
 
-				if (!SetConsoleCursorInfo (ScreenBuffer, ref info))
+				if (!SetConsoleCursorInfo (OutputHandle, ref info))
 					return false;
 
 				currentCursorVisibility = visibility;
@@ -165,28 +164,28 @@ namespace Terminal.Gui {
 			}
 
 			ConsoleMode = originalConsoleMode;
-			if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
-				var err = Marshal.GetLastWin32Error ();
-				Console.WriteLine ("Error: {0}", err);
-			}
+			//if (!SetConsoleActiveScreenBuffer (OutputHandle)) {
+			//	var err = Marshal.GetLastWin32Error ();
+			//	Console.WriteLine ("Error: {0}", err);
+			//}
 
-			if (ScreenBuffer != IntPtr.Zero) {
-				CloseHandle (ScreenBuffer);
-			}
+			//if (ScreenBuffer != IntPtr.Zero) {
+			//	CloseHandle (ScreenBuffer);
+			//}
 
-			ScreenBuffer = IntPtr.Zero;
+			//ScreenBuffer = IntPtr.Zero;
 		}
 
 		internal Size GetConsoleBufferWindow (out Point position)
 		{
-			if (ScreenBuffer == IntPtr.Zero) {
+			if (OutputHandle == IntPtr.Zero) {
 				position = Point.Empty;
 				return Size.Empty;
 			}
 
 			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
 			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-			if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+			if (!GetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
 				//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
 				position = Point.Empty;
 				return Size.Empty;
@@ -212,65 +211,65 @@ namespace Terminal.Gui {
 			return sz;
 		}
 
-		internal Size SetConsoleWindow (short cols, short rows)
-		{
-			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
-			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-
-			if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-			var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer);
-			var newCols = Math.Min (cols, maxWinSize.X);
-			var newRows = Math.Min (rows, maxWinSize.Y);
-			csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1));
-			csbi.srWindow = new SmallRect (0, 0, newCols, newRows);
-			csbi.dwMaximumWindowSize = new Coord (newCols, newRows);
-			if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-			var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0));
-			if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
-				//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-				return new Size (cols, rows);
-			}
-			SetConsoleOutputWindow (csbi);
-			return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1);
-		}
-
-		void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
-		{
-			if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-		}
-
-		internal Size SetConsoleOutputWindow (out Point position)
-		{
-			if (ScreenBuffer == IntPtr.Zero) {
-				position = Point.Empty;
-				return Size.Empty;
-			}
-
-			var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
-			csbi.cbSize = (uint)Marshal.SizeOf (csbi);
-			if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-			var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
-				Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
-			position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
-			SetConsoleOutputWindow (csbi);
-			var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
-			if (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-			if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
-				throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
-			}
-
-			return sz;
-		}
+		//internal Size SetConsoleWindow (short cols, short rows)
+		//{
+		//	var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
+		//	csbi.cbSize = (uint)Marshal.SizeOf (csbi);
+
+		//	if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+		//	var maxWinSize = GetLargestConsoleWindowSize (ScreenBuffer);
+		//	var newCols = Math.Min (cols, maxWinSize.X);
+		//	var newRows = Math.Min (rows, maxWinSize.Y);
+		//	csbi.dwSize = new Coord (newCols, Math.Max (newRows, (short)1));
+		//	csbi.srWindow = new SmallRect (0, 0, newCols, newRows);
+		//	csbi.dwMaximumWindowSize = new Coord (newCols, newRows);
+		//	if (!SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+		//	var winRect = new SmallRect (0, 0, (short)(newCols - 1), (short)Math.Max (newRows - 1, 0));
+		//	if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
+		//		//throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//		return new Size (cols, rows);
+		//	}
+		//	SetConsoleOutputWindow (csbi);
+		//	return new Size (winRect.Right + 1, newRows - 1 < 0 ? 0 : winRect.Bottom + 1);
+		//}
+
+		//void SetConsoleOutputWindow (CONSOLE_SCREEN_BUFFER_INFOEX csbi)
+		//{
+		//	if (ScreenBuffer != IntPtr.Zero && !SetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+		//}
+
+		//internal Size SetConsoleOutputWindow (out Point position)
+		//{
+		//	if (ScreenBuffer == IntPtr.Zero) {
+		//		position = Point.Empty;
+		//		return Size.Empty;
+		//	}
+
+		//	var csbi = new CONSOLE_SCREEN_BUFFER_INFOEX ();
+		//	csbi.cbSize = (uint)Marshal.SizeOf (csbi);
+		//	if (!GetConsoleScreenBufferInfoEx (ScreenBuffer, ref csbi)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+		//	var sz = new Size (csbi.srWindow.Right - csbi.srWindow.Left + 1,
+		//		Math.Max (csbi.srWindow.Bottom - csbi.srWindow.Top + 1, 0));
+		//	position = new Point (csbi.srWindow.Left, csbi.srWindow.Top);
+		//	SetConsoleOutputWindow (csbi);
+		//	var winRect = new SmallRect (0, 0, (short)(sz.Width - 1), (short)Math.Max (sz.Height - 1, 0));
+		//	if (!SetConsoleScreenBufferInfoEx (OutputHandle, ref csbi)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+		//	if (!SetConsoleWindowInfo (OutputHandle, true, ref winRect)) {
+		//		throw new System.ComponentModel.Win32Exception (Marshal.GetLastWin32Error ());
+		//	}
+
+		//	return sz;
+		//}
 
 		//bool ContinueListeningForConsoleEvents = true;
 
@@ -734,7 +733,7 @@ namespace Terminal.Gui {
 			WinConsole = new WindowsConsole ();
 			clipboard = new WindowsClipboard ();
 
-			isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null;
+			isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null || Environment.GetEnvironmentVariable ("VSAPPIDNAME") != null;
 		}
 
 		public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
@@ -748,28 +747,28 @@ namespace Terminal.Gui {
 
 			mLoop.ProcessInput = (e) => ProcessInput (e);
 
-			mLoop.WinChanged = (e) => {
-				ChangeWin (e);
-			};
-		}
-
-		private void ChangeWin (Size e)
-		{
-			var w = e.Width;
-			if (w == cols - 3 && e.Height < rows) {
-				w += 3;
-			}
-			var newSize = WinConsole.SetConsoleWindow (
-				(short)Math.Max (w, 16), (short)Math.Max (e.Height, 0));
-
-			left = 0;
-			top = 0;
-			cols = newSize.Width;
-			rows = newSize.Height;
-			ResizeScreen ();
-			UpdateOffScreen ();
-			TerminalResized.Invoke ();
-		}
+			//mLoop.WinChanged = (e) => {
+			//	ChangeWin (e);
+			//};
+		}
+
+		//private void ChangeWin (Size e)
+		//{
+		//	var w = e.Width;
+		//	if (w == cols - 3 && e.Height < rows) {
+		//		w += 3;
+		//	}
+		//	var newSize = WinConsole.SetConsoleWindow (
+		//		(short)Math.Max (w, 16), (short)Math.Max (e.Height, 0));
+
+		//	left = 0;
+		//	top = 0;
+		//	cols = newSize.Width;
+		//	rows = newSize.Height;
+		//	ResizeScreen ();
+		//	UpdateOffScreen ();
+		//	TerminalResized.Invoke ();
+		//}
 
 		void ProcessInput (WindowsConsole.InputRecord inputEvent)
 		{
@@ -893,6 +892,14 @@ namespace Terminal.Gui {
 			case WindowsConsole.EventType.Focus:
 				keyModifiers = null;
 				break;
+
+			case WindowsConsole.EventType.WindowBufferSize:
+				cols = inputEvent.WindowBufferSizeEvent.size.X;
+				rows = inputEvent.WindowBufferSizeEvent.size.Y;
+
+				ResizeScreen ();
+				TerminalResized.Invoke ();
+				break;
 			}
 		}
 
@@ -1970,7 +1977,21 @@ namespace Terminal.Gui {
 	class WindowsClipboard : ClipboardBase {
 		public WindowsClipboard ()
 		{
-			IsSupported = IsClipboardFormatAvailable (cfUnicodeText);
+			IsSupported = CheckClipboardIsAvailable ();
+		}
+
+		private static bool CheckClipboardIsAvailable ()
+		{
+			// Attempt to open the clipboard
+			if (OpenClipboard (IntPtr.Zero)) {
+				// Clipboard is available
+				// Close the clipboard after use
+				CloseClipboard ();
+
+				return true;
+			}
+			// Clipboard is not available
+			return false;
 		}
 
 		public override bool IsSupported { get; }

+ 1 - 1
Terminal.Gui/README.md

@@ -17,7 +17,7 @@ All files required to build the **Terminal.Gui** library (and NuGet package).
     - `Window` - Derived from `TopLevel`; implements toplevel views with a visible frame and Title.
 - `Types/` - A folder (not namespace) containing implementations of `Point`, `Rect`, and `Size` which are ancient versions of the modern `System.Drawing.Point`, `System.Drawing.Size`, and `System.Drawning.Rectangle`.
 - `ConsoleDrivers/` - Source files for the three `ConsoleDriver`-based drivers: .NET: `NetDriver`, Unix & Mac: `UnixDriver`, and Windows: `WindowsDriver`.
-- `Views/` - A folder (not namespace) containing the source for all built-in classes that drive from `View` (non-modals). 
+- `Views/` - A folder (not namespace) containing the source for all built-in classes that derive from `View` (non-modals). 
 - `Windows/` - A folder (not namespace) containing the source of all built-in classes that derive from `Window`.
 
 ## Version numbers

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

@@ -1238,7 +1238,7 @@ namespace Terminal.Gui {
 				mi = openCurrentMenu.barItems.Children [openCurrentMenu.current];
 			} else if (openCurrentMenu.barItems.IsTopLevel) {
 				mi = openCurrentMenu.barItems;
-			} else {
+			} else if (openCurrentMenu?.current > -1) {
 				mi = openMenu.barItems.Children [openMenu.current];
 			}
 			MenuOpened?.Invoke (mi);

+ 1 - 1
UICatalog/UICatalog.csproj

@@ -21,7 +21,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
-    <PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
+    <PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
     <PackageReference Include="CsvHelper" Version="33.0.1" />
     <PackageReference Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
   </ItemGroup>

+ 4 - 8
UnitTests/Menus/MenuTests.cs

@@ -219,8 +219,7 @@ Edit
 				View = mCurrent
 			}));
 			Assert.True (menu.IsMenuOpen);
-			Assert.Equal ("_File", miCurrent.Parent.Title);
-			Assert.Equal ("_New", miCurrent.Title);
+			Assert.Null (miCurrent);
 
 			Assert.True (mCurrent.MouseEvent (new MouseEvent () {
 				X = 1,
@@ -229,8 +228,7 @@ Edit
 				View = mCurrent
 			}));
 			Assert.True (menu.IsMenuOpen);
-			Assert.Equal ("_File", miCurrent.Parent.Title);
-			Assert.Equal ("_New", miCurrent.Title);
+			Assert.Null (miCurrent);
 
 			Assert.True (mCurrent.MouseEvent (new MouseEvent () {
 				X = 1,
@@ -239,8 +237,7 @@ Edit
 				View = mCurrent
 			}));
 			Assert.True (menu.IsMenuOpen);
-			Assert.Equal ("_File", miCurrent.Parent.Title);
-			Assert.Equal ("_Save", miCurrent.Title);
+			Assert.Null (miCurrent);
 
 			// close the menu
 			Assert.True (menu.MouseEvent (new MouseEvent () {
@@ -265,8 +262,7 @@ Edit
 
 			Assert.True (mCurrent.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ())));
 			Assert.True (menu.IsMenuOpen);
-			Assert.Equal ("_File", miCurrent.Parent.Title);
-			Assert.Equal ("_New", miCurrent.Title);
+			Assert.Null (miCurrent);
 
 			// close the menu
 			Assert.True (menu.ProcessHotKey (new KeyEvent (Key.F9, new KeyModifiers ())));

+ 2 - 2
UnitTests/UnitTests.csproj

@@ -19,10 +19,10 @@
   </PropertyGroup>
   <ItemGroup>
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
-    <PackageReference Include="ReportGenerator" Version="5.3.7" />
+    <PackageReference Include="ReportGenerator" Version="5.3.8" />
     <PackageReference Include="System.Collections" Version="4.3.0" />
     <PackageReference Include="xunit" Version="2.9.0" />
-    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.1">
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>