From 4d81513b81266f0b30235709c71357aea055d7be Mon Sep 17 00:00:00 2001 From: Cedric Willekens Date: Sun, 5 May 2024 21:00:13 +0200 Subject: [PATCH 01/23] Fix gha smells: - Avoid running CI related actions when no source code has changed - Avoid executing scheduled workflows on forks - Avoid jobs without timeouts --- .github/workflows/api-docs.yml | 2 ++ .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/codeql.yml | 1 + .github/workflows/dotnet-core.yml | 2 +- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api-docs.yml b/.github/workflows/api-docs.yml index a97953233..274bf6706 100644 --- a/.github/workflows/api-docs.yml +++ b/.github/workflows/api-docs.yml @@ -4,6 +4,8 @@ on: push: # only publish v2 (main or develop); v2 is published via the Terminal.GuiV2Docs repo branches: [main, develop] + paths: + - docfx/** permissions: id-token: write diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 78c4dc0fb..5103f7bf0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -25,7 +25,7 @@ on: jobs: CodeQL-Build: - + if: github.repository == 'gui-cs/Terminal.Gui'|| github.event_name == 'schedule' runs-on: ubuntu-latest steps: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6e2fd86ac..e7dad3b01 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -29,6 +29,7 @@ jobs: # Consider using larger runners for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + if: github.repository == 'gui-cs/Terminal.Gui'|| github.event_name == 'schedule' permissions: actions: read contents: read diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index f5e5ee42c..940d19604 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -13,7 +13,7 @@ on: jobs: build: runs-on: ubuntu-latest - + timeout-minutes: 10 steps: - uses: actions/checkout@v4 From 87ea75b3c11d797a65260c42bb60824a7547bc9b Mon Sep 17 00:00:00 2001 From: BDisp Date: Sun, 26 May 2024 17:23:19 +0100 Subject: [PATCH 02/23] v1 Fixes #2897. ListView ListWrapper - marking does work if you give an IList which in which the count changes --- Terminal.Gui/Views/ListView.cs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index e0d4edbda..f340d7ebd 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -749,6 +749,11 @@ namespace Terminal.Gui { public void EnsureSelectedItemVisible () { SuperView?.LayoutSubviews (); + // If last item is selected and is removed, ensures a valid selected item + if (Source != null && selected > Source.Count - 1) { + SelectedItem = Source.Count - 1; + SetNeedsDisplay (); + } if (selected < top) { top = selected; } else if (Frame.Height > 0 && selected >= top + Frame.Height) { @@ -831,11 +836,30 @@ namespace Terminal.Gui { } /// - public int Count => src != null ? src.Count : 0; + public int Count { + get { + CheckAndResizeMarksIfRequired (); + return src?.Count ?? 0; + } + } /// public int Length => len; + void CheckAndResizeMarksIfRequired () + { + if (count != src.Count) { + count = src.Count; + BitArray newMarks = new BitArray (count); + for (var i = 0; i < Math.Min (marks.Length, newMarks.Length); i++) { + newMarks [i] = marks [i]; + } + marks = newMarks; + + len = GetMaxLengthItem (); + } + } + int GetMaxLengthItem () { if (src == null || src?.Count == 0) { @@ -896,7 +920,7 @@ namespace Terminal.Gui { /// public bool IsMarked (int item) { - if (item >= 0 && item < count) + if (item >= 0 && item < Count) return marks [item]; return false; } @@ -904,7 +928,7 @@ namespace Terminal.Gui { /// public void SetMark (int item, bool value) { - if (item >= 0 && item < count) + if (item >= 0 && item < Count) marks [item] = value; } From d7b0899f2beffaeacba6bc28a642ac477f302155 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sun, 26 May 2024 17:39:34 +0100 Subject: [PATCH 03/23] Prevent System.NullReferenceException. --- Terminal.Gui/Views/ListView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index f340d7ebd..0ef93d00e 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -848,7 +848,7 @@ namespace Terminal.Gui { void CheckAndResizeMarksIfRequired () { - if (count != src.Count) { + if (src != null && count != src.Count) { count = src.Count; BitArray newMarks = new BitArray (count); for (var i = 0; i < Math.Min (marks.Length, newMarks.Length); i++) { From d5bf412d376fbfc89440ea24370c6a685fb18411 Mon Sep 17 00:00:00 2001 From: BDisp Date: Wed, 29 May 2024 12:34:59 +0100 Subject: [PATCH 04/23] Adjust the top considering the selected item and the frame height. --- Terminal.Gui/Views/ListView.cs | 6 ++++-- UnitTests/Views/ListViewTests.cs | 18 +++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 0ef93d00e..ae6528d94 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -601,10 +601,12 @@ namespace Terminal.Gui { /// public virtual bool MoveEnd () { - if (source.Count > 0 && selected != source.Count - 1) { + if (source?.Count > 0 && selected != source.Count - 1) { selected = source.Count - 1; if (top + selected > Frame.Height - 1) { - top = selected; + top = selected < Frame.Height - 1 + ? Math.Max (Frame.Height - selected + 1, 0) + : Math.Max (selected - Frame.Height + 1, 0); } OnSelectedChanged (); SetNeedsDisplay (); diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs index f705dab25..1f6589204 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/UnitTests/Views/ListViewTests.cs @@ -300,16 +300,16 @@ namespace Terminal.Gui.ViewTests { Assert.Equal (19, lv.SelectedItem); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌──────────┐ +│Line10 │ +│Line11 │ +│Line12 │ +│Line13 │ +│Line14 │ +│Line15 │ +│Line16 │ +│Line17 │ +│Line18 │ │Line19 │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ -│ │ └──────────┘", output); Assert.True (lv.ScrollUp (20)); From dee29b50b1f9cbb311e1da5d7e4561ee180ab8a0 Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 30 May 2024 21:50:17 +0100 Subject: [PATCH 05/23] Fixes #3518. v1 NetDriver throws System.InvalidOperationException when a key is pressed. --- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 811426f44..156c08f9d 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -177,7 +177,15 @@ namespace Terminal.Gui { ConsoleKeyInfo newConsoleKeyInfo = default; while (true) { - ConsoleKeyInfo consoleKeyInfo = Console.ReadKey (true); + ConsoleKeyInfo consoleKeyInfo; + + try { + consoleKeyInfo = Console.ReadKey (true); + } catch (InvalidOperationException ex) { + + return; + } + if ((consoleKeyInfo.KeyChar == (char)Key.Esc && !isEscSeq) || (consoleKeyInfo.KeyChar != (char)Key.Esc && isEscSeq)) { if (cki == null && consoleKeyInfo.KeyChar != (char)Key.Esc && isEscSeq) { From 322948cfaa661f5357989df594f012cf52b46cdd Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 30 May 2024 21:54:12 +0100 Subject: [PATCH 06/23] Ensures cursor visibility when cursor is visible. --- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 156c08f9d..69ccc22b0 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1351,7 +1351,11 @@ namespace Terminal.Gui { public override bool SetCursorVisibility (CursorVisibility visibility) { savedCursorVisibility = visibility; - return Console.CursorVisible = visibility == CursorVisibility.Default; + Console.Out.Write (visibility == CursorVisibility.Default + ? "\x1b[?25h" + : "\x1b[?25l"); + + return visibility == CursorVisibility.Default; } /// From 78de7b116ae7bd56bb18406492768f20355a0c0b Mon Sep 17 00:00:00 2001 From: BDisp Date: Thu, 30 May 2024 22:12:22 +0100 Subject: [PATCH 07/23] Add support for Suspend. --- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 69ccc22b0..af10b8b09 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1027,6 +1027,16 @@ namespace Terminal.Gui { public override void Suspend () { + if (Environment.OSVersion.Platform != PlatformID.Unix) { + return; + } + + StopReportingMouseMoves (); + Console.ResetColor (); + Console.Clear (); + Platform.Suspend (); + Application.Refresh (); + StartReportingMouseMoves (); } From 5b4195ed61f1271e68a3e610978aa5d9bc03ffa6 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sat, 1 Jun 2024 15:21:06 +0100 Subject: [PATCH 08/23] Restore buffer and cursor during suspend. --- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index af10b8b09..7d6ed0d69 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1034,12 +1034,22 @@ namespace Terminal.Gui { StopReportingMouseMoves (); Console.ResetColor (); Console.Clear (); + + //Disable alternative screen buffer. + Console.Out.Write ("\x1b[?1049l"); + + //Set cursor key to cursor. + Console.Out.Write ("\x1b[?25h"); + Platform.Suspend (); + + //Enable alternative screen buffer. + Console.Out.Write ("\x1b[?1049h"); + Application.Refresh (); StartReportingMouseMoves (); } - public override void SetAttribute (Attribute c) { base.SetAttribute (c); From f749eef8e9c28d8df34cf2d98b81381246ea8b62 Mon Sep 17 00:00:00 2001 From: BDisp Date: Sun, 2 Jun 2024 20:03:29 +0100 Subject: [PATCH 09/23] Remove InvalidOperationException and use Task.Delay with CancellationTokenSource. --- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 92 +++++++++++++----------- Terminal.Gui/Core/Application.cs | 2 +- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 7d6ed0d69..1e02a03ae 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -113,7 +113,9 @@ namespace Terminal.Gui { ConsoleDriver consoleDriver; volatile ConsoleKeyInfo [] cki = null; static volatile bool isEscSeq; - bool stopTasks; + + internal CancellationTokenSource TokenSource = new CancellationTokenSource (); + #if PROCESS_REQUEST bool neededProcessRequest; #endif @@ -125,21 +127,13 @@ namespace Terminal.Gui { throw new ArgumentNullException ("Console driver instance must be provided."); } this.consoleDriver = consoleDriver; - Task.Run (ProcessInputResultQueue); - Task.Run (CheckWinChange); - } - - internal void StopTasks () - { - stopTasks = true; + Task.Run (ProcessInputResultQueue, TokenSource.Token); + Task.Run (CheckWinChange, TokenSource.Token); } public InputResult? ReadConsoleInput () { - while (true) { - if (stopTasks) { - return null; - } + while (!TokenSource.IsCancellationRequested) { waitForStart.Set (); winChange.Set (); @@ -154,11 +148,13 @@ namespace Terminal.Gui { return inputResultQueue.Dequeue (); } } + + return null; } void ProcessInputResultQueue () { - while (true) { + while (!TokenSource.IsCancellationRequested) { waitForStart.Wait (); waitForStart.Reset (); @@ -176,12 +172,19 @@ namespace Terminal.Gui { ConsoleModifiers mod = 0; ConsoleKeyInfo newConsoleKeyInfo = default; - while (true) { - ConsoleKeyInfo consoleKeyInfo; + while (!TokenSource.IsCancellationRequested) { + ConsoleKeyInfo consoleKeyInfo = default; try { - consoleKeyInfo = Console.ReadKey (true); - } catch (InvalidOperationException ex) { + if (Console.KeyAvailable) { + consoleKeyInfo = Console.ReadKey (true); + } else { + Task.Delay (100, TokenSource.Token).Wait (TokenSource.Token); + if (Console.KeyAvailable) { + consoleKeyInfo = Console.ReadKey (true); + } + } + } catch (OperationCanceledException) { return; } @@ -209,18 +212,19 @@ namespace Terminal.Gui { } break; } else { - GetConsoleInputType (consoleKeyInfo); - break; + if (consoleKeyInfo != default) { + GetConsoleInputType (consoleKeyInfo); + break; + } } + + TokenSource.Token.ThrowIfCancellationRequested (); } } void CheckWinChange () { - while (true) { - if (stopTasks) { - return; - } + while (!TokenSource.IsCancellationRequested) { winChange.Wait (); winChange.Reset (); WaitWinChange (); @@ -230,13 +234,16 @@ namespace Terminal.Gui { void WaitWinChange () { - while (true) { - // Wait for a while then check if screen has changed sizes - Task.Delay (500).Wait (); + while (!TokenSource.IsCancellationRequested) { + try { + // Wait for a while then check if screen has changed sizes + Task.Delay (500, TokenSource.Token).Wait (TokenSource.Token); + + } catch (OperationCanceledException) { - if (stopTasks) { return; } + int buffHeight, buffWidth; if (((NetDriver)consoleDriver).IsWinPlatform) { buffHeight = Math.Max (Console.BufferHeight, 0); @@ -699,7 +706,7 @@ namespace Terminal.Gui { public override void End () { - mainLoop.netEvents.StopTasks (); + mainLoop.Dispose (); if (IsWinPlatform) { NetWinConsole.Cleanup (); @@ -1455,7 +1462,7 @@ namespace Terminal.Gui { /// /// This implementation is used for NetDriver. /// - internal class NetMainLoop : IMainLoopDriver { + internal class NetMainLoop : IMainLoopDriver, IDisposable { ManualResetEventSlim keyReady = new ManualResetEventSlim (false); ManualResetEventSlim waitForProbe = new ManualResetEventSlim (false); Queue inputResult = new Queue (); @@ -1485,27 +1492,25 @@ namespace Terminal.Gui { void NetInputHandler () { - while (true) { + while (!tokenSource.IsCancellationRequested) { waitForProbe.Wait (); waitForProbe.Reset (); if (inputResult.Count == 0) { inputResult.Enqueue (netEvents.ReadConsoleInput ()); } - try { - while (inputResult.Peek () == null) { - inputResult.Dequeue (); - } - if (inputResult.Count > 0) { - keyReady.Set (); - } - } catch (InvalidOperationException) { } + while (inputResult.Count > 0 && inputResult.Peek () == null) { + inputResult.Dequeue (); + } + if (inputResult.Count > 0) { + keyReady.Set (); + } } } void IMainLoopDriver.Setup (MainLoop mainLoop) { this.mainLoop = mainLoop; - Task.Run (NetInputHandler); + Task.Run (NetInputHandler, tokenSource.Token); } void IMainLoopDriver.Wakeup () @@ -1535,8 +1540,7 @@ namespace Terminal.Gui { return inputResult.Count > 0 || CheckTimers (wait, out _); } - tokenSource.Dispose (); - tokenSource = new CancellationTokenSource (); + tokenSource.Token.ThrowIfCancellationRequested (); return true; } @@ -1569,5 +1573,11 @@ namespace Terminal.Gui { ProcessInput?.Invoke (inputResult.Dequeue ().Value); } } + + public void Dispose () + { + tokenSource.Cancel (); + netEvents.TokenSource.Cancel (); + } } } \ No newline at end of file diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs index 52343079b..9e981ce0d 100644 --- a/Terminal.Gui/Core/Application.cs +++ b/Terminal.Gui/Core/Application.cs @@ -1133,9 +1133,9 @@ namespace Terminal.Gui { // BUGBUG: MdiTop is not cleared here, but it should be? - MainLoop = null; Driver?.End (); Driver = null; + MainLoop = null; Iteration = null; RootMouseEvent = null; RootKeyEvent = null; From 7d8c5a2e5486c683c8c883285a32ac0e94f095fb Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 3 Jun 2024 01:52:07 +0100 Subject: [PATCH 10/23] Fixes #3527. v1 CursesDriver isn't updating the buffer on the UpdateOffScreen method. --- Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 0247b5671..fb5fa1c8c 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -752,9 +752,9 @@ namespace Terminal.Gui { contents = new int [Rows, Cols, 3]; for (int row = 0; row < Rows; row++) { for (int col = 0; col < Cols; col++) { - //Curses.move (row, col); - //Curses.attrset (Colors.TopLevel.Normal); - //Curses.addch ((int)(uint)' '); + Curses.move (row, col); + Curses.attrset (Colors.TopLevel.Normal); + Curses.addch ((int)(uint)' '); contents [row, col, 0] = ' '; contents [row, col, 1] = Colors.TopLevel.Normal; contents [row, col, 2] = 0; From 48334dead82ae5146f5b506c63e5362a584500d3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:42:17 +0000 Subject: [PATCH 11/23] Bump ReportGenerator from 5.3.4 to 5.3.6 Bumps [ReportGenerator](https://github.com/danielpalme/ReportGenerator) from 5.3.4 to 5.3.6. - [Release notes](https://github.com/danielpalme/ReportGenerator/releases) - [Commits](https://github.com/danielpalme/ReportGenerator/compare/v5.3.4...v5.3.6) --- updated-dependencies: - dependency-name: ReportGenerator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- UnitTests/UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index 7c4b4705a..d6e4f353a 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -19,7 +19,7 @@ - + From abdb7db1b89b7a7cc136e38c311b9c38fa1654fe Mon Sep 17 00:00:00 2001 From: BDisp Date: Mon, 17 Jun 2024 23:00:14 +0100 Subject: [PATCH 12/23] Fixes #3545. V1 Superview most focused view not sync with the overlapped view. --- Terminal.Gui/Core/Application.cs | 1 + Terminal.Gui/Core/View.cs | 4 ++++ Terminal.Gui/Core/Window.cs | 2 +- UnitTests/Application/ApplicationTests.cs | 18 +++++++++--------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs index 9e981ce0d..c7195e5d7 100644 --- a/Terminal.Gui/Core/Application.cs +++ b/Terminal.Gui/Core/Application.cs @@ -1037,6 +1037,7 @@ namespace Terminal.Gui { toplevel.LayoutSubviews (); toplevel.PositionToplevels (); toplevel.WillPresent (); + EnsuresTopOnFront (); if (refreshDriver) { MdiTop?.OnChildLoaded (toplevel); toplevel.OnLoaded (); diff --git a/Terminal.Gui/Core/View.cs b/Terminal.Gui/Core/View.cs index 5ea7785d1..25d765759 100644 --- a/Terminal.Gui/Core/View.cs +++ b/Terminal.Gui/Core/View.cs @@ -394,6 +394,10 @@ namespace Terminal.Gui { } } } + + if (SuperView is Toplevel && Application.Current?.Focused != SuperView) { + Application.EnsuresTopOnFront (); + } } OnCanFocusChanged (); SetNeedsDisplay (); diff --git a/Terminal.Gui/Core/Window.cs b/Terminal.Gui/Core/Window.cs index 8fbe05642..a63ebb873 100644 --- a/Terminal.Gui/Core/Window.cs +++ b/Terminal.Gui/Core/Window.cs @@ -104,7 +104,7 @@ namespace Terminal.Gui { public override void OnCanFocusChanged () { - if (MostFocused == null && CanFocus && Visible) { + if (HasFocus && MostFocused == null && CanFocus && Visible) { EnsureFocus (); } diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index d49250eab..2550a1bb3 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -771,28 +771,28 @@ namespace Terminal.Gui.ApplicationTests { Assert.True (win.HasFocus); Assert.True (win2.CanFocus); Assert.False (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); Assert.False (win2.HasFocus); - Assert.Equal ("win", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Pressed }); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released }); Assert.Null (Toplevel.dragPosition); } @@ -816,35 +816,35 @@ namespace Terminal.Gui.ApplicationTests { Assert.True (win.HasFocus); Assert.True (win2.CanFocus); Assert.False (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); win.CanFocus = false; Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); win.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Pressed }); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released }); Assert.Null (Toplevel.dragPosition); } From cd63813835744e4bb577e8dc949a855cfb55572c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:57:09 +0000 Subject: [PATCH 13/23] Bump CsvHelper from 32.0.3 to 33.0.1 Bumps [CsvHelper](https://github.com/JoshClose/CsvHelper) from 32.0.3 to 33.0.1. - [Commits](https://github.com/JoshClose/CsvHelper/commits) --- updated-dependencies: - dependency-name: CsvHelper dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- UICatalog/UICatalog.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UICatalog/UICatalog.csproj b/UICatalog/UICatalog.csproj index 6a82bb666..17b45e7c8 100644 --- a/UICatalog/UICatalog.csproj +++ b/UICatalog/UICatalog.csproj @@ -22,7 +22,7 @@ - + From fe138f3498a5e23c1cc9290bf35c0549f937ff5a Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 25 Jun 2024 00:50:13 +0100 Subject: [PATCH 14/23] Fixes #2598. Trying to run self-contained application on Ubuntu 22 (Linux-x64), error regarding libdl.so --- Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs index 40d51be4f..7d27b56ee 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs @@ -256,7 +256,7 @@ namespace Unix.Terminal { /// to avoid the dependency on libc-dev Linux. /// static class CoreCLR { -#if NET7_0 +#if NET7_0 || NET8_0 // Custom resolver to support true single-file apps // (those which run directly from bundle; in-memory). // -1 on Unix means self-referencing binary (libcoreclr.so) From 8c3971c7fe3483db74aa95f6589984e47a9e9e55 Mon Sep 17 00:00:00 2001 From: BDisp Date: Tue, 25 Jun 2024 16:07:15 +0100 Subject: [PATCH 15/23] Add net6.0 target to the project. --- Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs | 2 +- Terminal.Gui/Terminal.Gui.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs index 7d27b56ee..48c375a6a 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnmanagedLibrary.cs @@ -256,7 +256,7 @@ namespace Unix.Terminal { /// to avoid the dependency on libc-dev Linux. /// static class CoreCLR { -#if NET7_0 || NET8_0 +#if NET6_0_OR_GREATER // Custom resolver to support true single-file apps // (those which run directly from bundle; in-memory). // -1 on Unix means self-referencing binary (libcoreclr.so) diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index 9162889d1..bd919e2aa 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -20,7 +20,7 @@ portable - net472;netstandard2.0;netstandard2.1;net7.0;net8.0 + net472;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0 Terminal.Gui Terminal.Gui true From 1b7f1e71fe203703daaa7bac764fa6f53a9a6a00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:17:19 +0000 Subject: [PATCH 16/23] Bump ReportGenerator from 5.3.6 to 5.3.7 Bumps [ReportGenerator](https://github.com/danielpalme/ReportGenerator) from 5.3.6 to 5.3.7. - [Release notes](https://github.com/danielpalme/ReportGenerator/releases) - [Commits](https://github.com/danielpalme/ReportGenerator/compare/v5.3.6...v5.3.7) --- updated-dependencies: - dependency-name: ReportGenerator dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- UnitTests/UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index d6e4f353a..a5f4cdc1a 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -19,7 +19,7 @@ - + From 482cd9629fa2e3aa54b76cd41ede6bedfe033647 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:17:43 +0000 Subject: [PATCH 17/23] Bump Microsoft.VisualStudio.Azure.Containers.Tools.Targets Bumps Microsoft.VisualStudio.Azure.Containers.Tools.Targets from 1.20.1 to 1.21.0. --- updated-dependencies: - dependency-name: Microsoft.VisualStudio.Azure.Containers.Tools.Targets dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- UICatalog/UICatalog.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UICatalog/UICatalog.csproj b/UICatalog/UICatalog.csproj index 17b45e7c8..89dcd4c0c 100644 --- a/UICatalog/UICatalog.csproj +++ b/UICatalog/UICatalog.csproj @@ -20,7 +20,7 @@ - + From 14061dbbaeede2b0a998b8af38a80c696983e11c Mon Sep 17 00:00:00 2001 From: Tig Date: Wed, 3 Jul 2024 10:29:35 -0600 Subject: [PATCH 18/23] Fixed Example.cs --- Example/Example.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Example/Example.cs b/Example/Example.cs index 069e366d5..399de8c9c 100644 --- a/Example/Example.cs +++ b/Example/Example.cs @@ -7,22 +7,23 @@ using Terminal.Gui; Application.Run (); -System.Console.WriteLine ($"Username: {((ExampleWindow)Application.Top).usernameText.Text}"); - // Before the application exits, reset Terminal.Gui for clean shutdown Application.Shutdown (); +System.Console.WriteLine ($@"Username: {ExampleWindow.Username}"); + // Defines a top-level window with border and title public class ExampleWindow : Window { + public static string Username { get; internal set; } public TextField usernameText; - + public ExampleWindow () { Title = "Example App (Ctrl+Q to quit)"; // Create input components and labels - var usernameLabel = new Label () { - Text = "Username:" + var usernameLabel = new Label () { + Text = "Username:" }; usernameText = new TextField ("") { @@ -50,7 +51,7 @@ public class ExampleWindow : Window { // Create login button var btnLogin = new Button () { Text = "Login", - Y = Pos.Bottom(passwordLabel) + 1, + Y = Pos.Bottom (passwordLabel) + 1, // center the login button horizontally X = Pos.Center (), IsDefault = true, @@ -60,6 +61,7 @@ public class ExampleWindow : Window { btnLogin.Clicked += () => { if (usernameText.Text == "admin" && passwordText.Text == "password") { MessageBox.Query ("Logging In", "Login Successful", "Ok"); + Username = usernameText.Text.ToString (); Application.RequestStop (); } else { MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok"); From fbaf610de4563ca306cc6e1f3fcbc69665e388ba Mon Sep 17 00:00:00 2001 From: Tig Date: Wed, 3 Jul 2024 10:30:22 -0600 Subject: [PATCH 19/23] Fixed Readme --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7326a9232..be462f5a2 100644 --- a/README.md +++ b/README.md @@ -63,28 +63,32 @@ The team is looking forward to seeing new amazing projects made by the community The following example shows a basic Terminal.Gui application in C#: ```csharp +// This is a simple example application. For the full range of functionality +// see the UICatalog project + // A simple Terminal.Gui example in C# - using C# 9.0 Top-level statements using Terminal.Gui; Application.Run (); -System.Console.WriteLine ($"Username: {((ExampleWindow)Application.Top).usernameText.Text}"); - // Before the application exits, reset Terminal.Gui for clean shutdown Application.Shutdown (); +System.Console.WriteLine ($@"Username: {ExampleWindow.Username}"); + // Defines a top-level window with border and title public class ExampleWindow : Window { + public static string Username { get; internal set; } public TextField usernameText; - + public ExampleWindow () { Title = "Example App (Ctrl+Q to quit)"; // Create input components and labels - var usernameLabel = new Label () { - Text = "Username:" + var usernameLabel = new Label () { + Text = "Username:" }; usernameText = new TextField ("") { @@ -112,7 +116,7 @@ public class ExampleWindow : Window { // Create login button var btnLogin = new Button () { Text = "Login", - Y = Pos.Bottom(passwordLabel) + 1, + Y = Pos.Bottom (passwordLabel) + 1, // center the login button horizontally X = Pos.Center (), IsDefault = true, @@ -122,6 +126,7 @@ public class ExampleWindow : Window { btnLogin.Clicked += () => { if (usernameText.Text == "admin" && passwordText.Text == "password") { MessageBox.Query ("Logging In", "Login Successful", "Ok"); + Username = usernameText.Text.ToString (); Application.RequestStop (); } else { MessageBox.ErrorQuery ("Logging In", "Incorrect username or password", "Ok"); From bf92d1291b83962426842cf404a9868e4824024c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:20:10 -0600 Subject: [PATCH 20/23] Bump xunit from 2.8.1 to 2.9.0 (#3596) Bumps xunit from 2.8.1 to 2.9.0. --- updated-dependencies: - dependency-name: xunit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- UnitTests/UnitTests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index a5f4cdc1a..d7e5c2d2a 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -21,7 +21,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From c08dc11c933143c10b8d0a2c084ecafadcda52e4 Mon Sep 17 00:00:00 2001 From: Tig Date: Thu, 11 Jul 2024 16:17:23 -0600 Subject: [PATCH 21/23] Updated readme for v1.17.1 --- Terminal.Gui/README.md | 46 +++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/Terminal.Gui/README.md b/Terminal.Gui/README.md index ca0257e73..68c7e8f5d 100644 --- a/Terminal.Gui/README.md +++ b/Terminal.Gui/README.md @@ -51,9 +51,9 @@ Doing so will update the `.csproj` files in your branch with version info, which The following actions will publish the Terminal.Gui package to Nuget: -* A new version tag is defined and pushed to `main` - this is the normal release process. -* A push to the `main` branch without a new version tag - this is a release-candidate build and will be of the form `1.2.3-rc.4` -* A push to the `develop` branch - this is a pre-release build and will be of the form `1.2.3-pre.4` +* A new version tag is defined and pushed to `v1_release` - this is the normal release process. +* A push to the `v1_release` branch without a new version tag - this is a release-candidate build and will be of the form `1.2.3-rc.4` +* A push to the `v1_develop` branch - this is a pre-release build and will be of the form `1.2.3-pre.4` ## Publishing a Release of Terminal.Gui @@ -71,17 +71,17 @@ The `tag` must be of the form `v..`, e.g. `v1.2.3`. ### 1) Verify the `develop` branch is ready for release -* Ensure everything is committed and pushed to the `develop` branch -* Ensure your local `develop` branch is up-to-date with `upstream/develop` +* Ensure everything is committed and pushed to the `v1_develop` branch +* Ensure your local `v1_develop` branch is up-to-date with `upstream/v1_develop` -### 2) Create a pull request for the release in the `develop` branch +### 2) Create a pull request for the release in the `v1_develop` branch The PR title should be of the form "Release v1.2.3" ```powershell -git checkout develop -git pull upstream develop -git checkout -b v2_3_4 +git checkout v1_develop +git pull upstream v1_develop +git checkout -b v1_2_3 git add . git commit -m "Release v1.2.3" @@ -90,36 +90,36 @@ git push Go to the link printed by `git push` and fill out the Pull Request. -### 3) On github.com, verify the build action worked on your fork, then merge the PR to `develop` +### 3) On github.com, verify the build action worked on your fork, then merge the PR to `v1_develop` * Merging the PR will trigger the publish action on `upstream` (the main repo) and publish the Nuget package as a pre-release (e.g. `1.2.3-pre.1`). ### 4) Pull the merged `develop` from `upstream` ```powershell -git checkout develop -git pull upstream develop +git checkout v1_develop +git pull upstream v1_develop ``` ### 5) Merge `develop` into `main` ```powershell -git checkout main -git pull upstream main -git merge develop +git checkout v1_release +git pull upstream v1_release +git merge v1_develop ``` Fix any merge errors. -At this point, to release a release candidate, push the `main` branch `upstream` without a new tag. +At this point, to release a release candidate, push the `v1_release` branch `upstream` without a new tag. ```powershell -git push upstream main +git push upstream v1_release ``` This will publish `1.2.3-rc.1` to Nuget. -### 6) Create a new annotated tag for the release on `main` +### 6) Create a new annotated tag for the release on `v1_release` ```powershell git tag v1.2.3 -a -m "Release v1.2.3" @@ -146,13 +146,13 @@ https://www.nuget.org/packages/Terminal.Gui Generate release notes with the list of PRs since the last release. -### 11) Update the `develop` branch with the new version +### 11) Update the `v1_develop` branch with the new version ```powershell -git checkout develop -git pull upstream develop -git merge main -git push upstream develop +git checkout v1_develop +git pull upstream v1_develop +git merge v1_release +git push upstream v1_develop ``` ## Nuget From 847e71012f8d8d144fb02cc46c5a079c65024047 Mon Sep 17 00:00:00 2001 From: Tig Date: Thu, 11 Jul 2024 16:23:09 -0600 Subject: [PATCH 22/23] Touched application.cs to force a build --- Terminal.Gui/Core/Application.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/Core/Application.cs b/Terminal.Gui/Core/Application.cs index c7195e5d7..1af183d58 100644 --- a/Terminal.Gui/Core/Application.cs +++ b/Terminal.Gui/Core/Application.cs @@ -53,7 +53,7 @@ namespace Terminal.Gui { /// /// /// When invoked sets the SynchronizationContext to one that is tied - /// to the mainloop, allowing user code to use async/await. + /// to the MainLoop, allowing user code to use async/await. /// /// public static class Application { From 5353f66c4bf6f723cbe56ea5c9e620aa95bb4b8e Mon Sep 17 00:00:00 2001 From: Tig Date: Thu, 11 Jul 2024 16:30:28 -0600 Subject: [PATCH 23/23] Fixed yml --- .github/workflows/api-docs.yml | 2 +- .github/workflows/dotnet-core.yml | 4 ++-- .github/workflows/publish.yml | 2 +- CONTRIBUTING.md | 4 ++-- GitVersion.yml | 19 ++++++++++--------- README.md | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.github/workflows/api-docs.yml b/.github/workflows/api-docs.yml index 274bf6706..92caf5b21 100644 --- a/.github/workflows/api-docs.yml +++ b/.github/workflows/api-docs.yml @@ -3,7 +3,7 @@ name: Build and publish API docs on: push: # only publish v2 (main or develop); v2 is published via the Terminal.GuiV2Docs repo - branches: [main, develop] + branches: [v1_release, v1_develop] paths: - docfx/** diff --git a/.github/workflows/dotnet-core.yml b/.github/workflows/dotnet-core.yml index 940d19604..750f7d93f 100644 --- a/.github/workflows/dotnet-core.yml +++ b/.github/workflows/dotnet-core.yml @@ -2,11 +2,11 @@ name: .NET Core on: push: - branches: [ main, develop ] + branches: [ v1_release, v1_develop ] paths-ignore: - '**.md' pull_request: - branches: [ main, develop ] + branches: [ v1_release, v1_develop ] paths-ignore: - '**.md' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 69913111f..39ba8ccd5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: Publish Terminal.Gui on: push: - branches: [ main, develop, v2_release, v2_develop ] + branches: [ v1_release, v1_develop, v2_release, v2_develop ] tags: - v* paths-ignore: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef6426867..75cc209ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,8 +12,8 @@ We welcome contributions from the community. See [Issues](https://github.com/gui Terminal.Gui uses the [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/) branching model. -* The `main` branch is always stable, and always matches the most recently released Nuget package. -* The `develop` branch is where bug-fixes to v1.x happens. It is the default branch. +* The `v1_release` branch is always stable, and always matches the most recently released Nuget package. +* The `v1__develop` branch is where bug-fixes to v1.x happens. It is the default branch. * The `v2_develop` branch is where development on v2.x happens. ### Forking Terminal.Gui diff --git a/GitVersion.yml b/GitVersion.yml index f6ded5b00..138dc2ac9 100644 --- a/GitVersion.yml +++ b/GitVersion.yml @@ -2,25 +2,26 @@ mode: ContinuousDeployment tag-prefix: '[vV]' continuous-delivery-fallback-tag: pre branches: - develop: + v1_develop: mode: ContinuousDeployment tag: pre - regex: develop + regex: v1_develop source-branches: - - main + - v1_release pre-release-weight: 100 - main: + v1_release: tag: rc increment: Patch + regex: v1_release source-branches: - - develop - - main - feature: + - v1_develop + - v1_release + v1_feature: tag: useBranchName regex: ^features?[/-] source-branches: - - develop - - main + - v1_develop + - v1_release pull-request: tag: PullRequest.{BranchName} increment: Inherit diff --git a/README.md b/README.md index be462f5a2..d44d8ea80 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ dotnet run * [Conceptual Documentation](https://gui-cs.github.io/Terminal.Gui/docs/index.html) * [API Documentation](https://gui-cs.github.io/Terminal.Gui/api/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))_ +_The Documentation matches the most recent Nuget release from the `v1_release_` 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/docs/index.html) provides insight into core concepts.